Python中的多重继承
继承是实现代码可重用性的机制,因为一个类(子类)可以派生另一个类(父类)的属性。它还提供传递性,即。如果 C 类继承自 P,那么 C 的所有子类也将继承自 P。
多重继承
当一个类派生自多个基类时,它被称为多重继承。派生类继承了基本情况的所有特性。
Syntax:
Class Base1:
Body of the class
Class Base2:
Body of the class
Class Derived(Base1, Base2):
Body of the class
在接下来的部分中,我们将通过示例了解多重继承过程中面临的问题以及如何解决它。
钻石问题
它指的是当两个类 Class2 和 Class3 继承自超类 Class1 并且类 Class4 继承自 Class2 和 Class3 时出现的歧义。如果有一个方法“m”是 Class2 和 Class3 之一或两者中的一个被覆盖的方法,那么就会产生歧义,即 Class4 应该继承哪个方法“m”。
当两个类中的方法都被覆盖时
Python3
# Python Program to depict multiple inheritance
# when method is overridden in both classes
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
class Class3(Class1):
def m(self):
print("In Class3")
class Class4(Class2, Class3):
pass
obj = Class4()
obj.m()
Python3
# Python Program to depict multiple inheritance
# when method is overridden in one of the classes
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
pass
class Class3(Class1):
def m(self):
print("In Class3")
class Class4(Class2, Class3):
pass
obj = Class4()
obj.m()
Python3
# Python Program to depict multiple inheritance
# when every class defines the same method
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
class Class3(Class1):
def m(self):
print("In Class3")
class Class4(Class2, Class3):
def m(self):
print("In Class4")
obj = Class4()
obj.m()
Class2.m(obj)
Class3.m(obj)
Class1.m(obj)
Python3
# Python Program to depict multiple inheritance
# when we try to call the method m for Class1,
# Class2, Class3 from the method m of Class4
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
class Class3(Class1):
def m(self):
print("In Class3")
class Class4(Class2, Class3):
def m(self):
print("In Class4")
Class2.m(self)
Class3.m(self)
Class1.m(self)
obj = Class4()
obj.m()
Python3
# Python Program to depict multiple inheritance
# when we try to call m of Class1 from both m of
# Class2 and m of Class3
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
Class1.m(self)
class Class3(Class1):
def m(self):
print("In Class3")
Class1.m(self)
class Class4(Class2, Class3):
def m(self):
print("In Class4")
Class2.m(self)
Class3.m(self)
obj = Class4()
obj.m()
Python3
# Python program to demonstrate
# super()
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
super().m()
class Class3(Class1):
def m(self):
print("In Class3")
super().m()
class Class4(Class2, Class3):
def m(self):
print("In Class4")
super().m()
obj = Class4()
obj.m()
Python3
# Python program to demonstrate
# super()
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
super().m()
class Class3(Class1):
def m(self):
print("In Class3")
super().m()
class Class4(Class2, Class3):
def m(self):
print("In Class4")
super().m()
print(Class4.mro()) #This will print list
print(Class4.__mro__) #This will print tuple
输出:
In Class2
注意:当您调用 obj.m()(在 Class4 的实例上为 m)时,输出为 In Class2。如果 Class4 被声明为 Class4(Class3, Class2) 那么 obj.m() 的输出将是 In Class3。
当方法在其中一个类中被覆盖时
Python3
# Python Program to depict multiple inheritance
# when method is overridden in one of the classes
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
pass
class Class3(Class1):
def m(self):
print("In Class3")
class Class4(Class2, Class3):
pass
obj = Class4()
obj.m()
输出:
In Class3
当每个类定义相同的方法时
Python3
# Python Program to depict multiple inheritance
# when every class defines the same method
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
class Class3(Class1):
def m(self):
print("In Class3")
class Class4(Class2, Class3):
def m(self):
print("In Class4")
obj = Class4()
obj.m()
Class2.m(obj)
Class3.m(obj)
Class1.m(obj)
输出:
In Class4
In Class2
In Class3
In Class1
上面代码中方法 obj.m() 的输出是In Class4 。执行 Class4 的方法“m”。要执行其他类的方法“m”,可以使用类名来完成。
现在,要直接从 Class4 的方法“m”调用 Class1、Class2、Class3 的方法 m,请参见下面的示例
Python3
# Python Program to depict multiple inheritance
# when we try to call the method m for Class1,
# Class2, Class3 from the method m of Class4
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
class Class3(Class1):
def m(self):
print("In Class3")
class Class4(Class2, Class3):
def m(self):
print("In Class4")
Class2.m(self)
Class3.m(self)
Class1.m(self)
obj = Class4()
obj.m()
输出:
In Class4
In Class2
In Class3
In Class1
从 Class2 的“m”和 Class3 的“m”而不是 Class4 调用 Class1 的“m”如下所示:
Python3
# Python Program to depict multiple inheritance
# when we try to call m of Class1 from both m of
# Class2 and m of Class3
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
Class1.m(self)
class Class3(Class1):
def m(self):
print("In Class3")
Class1.m(self)
class Class4(Class2, Class3):
def m(self):
print("In Class4")
Class2.m(self)
Class3.m(self)
obj = Class4()
obj.m()
输出:
In Class4
In Class2
In Class1
In Class3
In Class1
上述代码的输出有一个与之相关的问题,Class1 的方法 m 被调用了两次。 Python借助 super()函数为上述问题提供了解决方案。让我们看看它是如何工作的。
超级函数
Python3
# Python program to demonstrate
# super()
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
super().m()
class Class3(Class1):
def m(self):
print("In Class3")
super().m()
class Class4(Class2, Class3):
def m(self):
print("In Class4")
super().m()
obj = Class4()
obj.m()
输出:
In Class4
In Class2
In Class3
In Class1
Super() 通常在实例初始化时与 __init__函数一起使用。超级函数得出结论,在方法解析顺序(MRO)的帮助下调用哪个方法。
方法解析顺序:
在Python中,无论是内置的还是用户定义的每个类都派生自对象类,并且所有对象都是类对象的实例。因此,对象类是所有其他类的基类。
在多重继承的情况下,首先在当前类中搜索给定的属性,如果没有找到,然后在父类中搜索。父类以左右方式搜索,每个类搜索一次。
如果我们看到上面的例子,那么搜索属性的顺序将是 Derived、Base1、Base2、object。遵循的顺序称为 Derived 类的线性化,并且该顺序是使用称为方法解析顺序 (MRO) 的一组规则找到的。
查看班级的 MRO:
- 使用 mro() 方法,它返回一个列表
例如。 Class4.mro() - 使用 _mro_ 属性,它返回一个元组
例如。 Class4.__mro__
例子:
Python3
# Python program to demonstrate
# super()
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
super().m()
class Class3(Class1):
def m(self):
print("In Class3")
super().m()
class Class4(Class2, Class3):
def m(self):
print("In Class4")
super().m()
print(Class4.mro()) #This will print list
print(Class4.__mro__) #This will print tuple
输出:
[
(