📜  Python中的多重继承

📅  最后修改于: 2022-05-13 01:55:44.237000             🧑  作者: Mango

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

输出: