Python多重继承

时间:2020-02-23 14:43:02  来源:igfitidea点击:

今天我们将学习python多重继承。

Python多重继承

这个名字说明了一切。
一类扩展一个以上的类称为多重继承。
这是python的很酷的特色之一,在某些情况下,它比java更加方便(Java不支持多重继承)。
Java没有它,因为有时多重继承可能会造成一些歧义。
我们将在本教程的后面部分讨论它。

多重继承与多层次继承

如果您以前熟悉多级继承,可能会感到困惑。
多级继承和多级继承之间的主要区别在于,在多级继承中,超类还可以继承另一个超类。
这样,可以在类之间创建不同级别的继承。

Python多重继承范例

让我们演示python多重继承的简短示例。

#definition of the class starts here  
class Person:  
  #defining constructor  
  def __init__(self, personName, personAge):  
      self.name = personName  
      self.age = personAge  

  #defining class methods  
  def showName(self):  
      print(self.name)  

  def showAge(self):  
      print(self.age)  

  #end of class definition  

# defining another class  
class Student: # Person is the  
  def __init__(self, studentId):  
      self.studentId = studentId  

  def getId(self):  
      return self.studentId  

class Resident(Person, Student): # extends both Person and Student class  
  def __init__(self, name, age, id):  
      Person.__init__(self, name, age)  
      Student.__init__(self, id)  

# Create an object of the subclass  
resident1 = Resident('John', 30, '102')  
resident1.showName()  
print(resident1.getId())

这里的Person和Student类是超类,Resident类是子类。
Resident类将Person和Student扩展为继承这两个类的属性。
如果您最了解python类和python继承,则该示例很容易理解。
此代码产生以下输出。

/usr/bin/python3.5 "/home/imtiaz/PycharmProjects/python tutorial - 1/multiple_inheritance.py"
John
102

Process finished with exit code 0

使用python多重继承解决冲突

让我们看另一个例子。

class A:  
  def __init__(self):  
      self.name = 'John'  
      self.age = 23  

  def getName(self):  
      return self.name  

class B:  
  def __init__(self):  
      self.name = 'Richard'  
      self.id = '32'  

  def getName(self):  
      return self.name  

class C(A, B):  
  def __init__(self):  
      A.__init__(self)  
      B.__init__(self)  

  def getName(self):  
      return self.name  

C1 = C()  
print(C1.getName())

C类继承了A和B。
它们都具有属性"名称"。
名称的值将从C继承自哪个类?是来自A还是来自B?你怎么看?好,输出为:

/usr/bin/python3.5 "/home/imtiaz/PycharmProjects/python tutorial - 1/multiple_inheritance.py"
Richard

Process finished with exit code 0

打印时的名称是" Richard"而不是" John"。
让我们尝试了解这里发生的情况。
在C的构造函数中,第一个调用的构造函数是A的构造函数。
因此,C中的name的值与A中的name的值相同。
但是此后,当调用B的构造函数时,name的值C中的name被B中的name值覆盖。
因此,C的name属性在打印时保留值'Richard'。
即使我们将C类声明为:

Class C(B, A):

层次结构完全取决于子类内部__init __()调用的顺序。
为了完美地处理它,有一个名为MRO(方法解析顺序)的协议。

方法解析顺序(MRO)

让我们用稍作修改的版本替换之前的代码。

class A:  
  def __init__(self):  
      super().__init__()  
      self.name = 'John'  
      self.age = 23  

  def getName(self):  
      return self.name  

class B:  
  def __init__(self):  
      super().__init__()  
      self.name = 'Richard'  
      self.id = '32'  

  def getName(self):  
      return self.name  

class C(A, B):  
  def __init__(self):  
      super().__init__()  

  def getName(self):  
      return self.name  

C1 = C()  
print(C1.getName())

你能猜出输出吗?好吧,让我们找出答案。

/usr/bin/python3.5 "/home/imtiaz/PycharmProjects/python tutorial - 1/multiple_inheritance.py"
John

Process finished with exit code 0

MRO的工作深度从左至右。
init__方法中的super()指示下一个层次结构中的类。
首先,C的super()表示A。
然后,A的构造函数中的super搜索其超类。
如果没有找到,它将执行其余代码并返回。
因此,这里调用构造函数的顺序是:C-> A-> B如果我们调用print(C .
mro__),那么我们可以看到MRO跟踪路由。

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

一旦调用了A的构造函数并访问了属性"名称",它就不会访问B中的属性"名称"。
要使用python多重继承,必须对MRO有更好的了解。