python 多继承与继承原理及多继承中super本质

一个子类可以继承多个父类,就是多继承,并且拥有所有父类的属性和方法。

例如 孩子会继承自己的父亲和母亲的特征。

目录

(一)语法

(二)多继承注意事项

(三)钻石继承

(四)多继承中super本质


(一)语法

class 子类名(父类名1,父类名2…) : pass

(二)多继承注意事项

如果子类和父类有相同的方法,就会调用子类中的方法。

如果不同的父类中存在着相同的方法名称,子类对象调用的时候会调用哪个父类中的方法呢? Python会根据 MRO(method resolution order) 方法解析顺序列表进行查找。

提示:开发时,需要避免这种容易产生混淆的情况!--如果父类之间存在同名的属性和方法,应尽量避免使用多继承。

以下代码可以确定就近原则:

class A(object):

    def test1(self):
        print('A test1')

    def test2(self):
        print('A test2')


class B(object):

    def test1(self):
        print('B test1')

    def test4(self):
        print('B test4')


class C(A, B):
    pass


# 父类有相同的方法的时候调用哪一个父类的?
c = C()
c.test1()
print(C.mro())  # 使用 mro()方法 来查看类的搜索路径
print(C.__mro__)  # 与上式一样作用
"""
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

"""

(三)钻石继承

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有父类的线性顺序列表,例如

为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。

而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:

1.子类会先于父类被检查

2.多个父类会根据它们在列表中的顺序被检查

3.如果对下一个类存在两个合法的选择,选择第一个父类

注意:D类有两个选择,默认选择B类执行。

在Python2.3之前,MRO是基于深度优先算法的,自2.3开始使用C3算法广度优先,定义类时需要继承object,这样的类称为新式类,否则为旧式类。下图左为旧式,右为新。

只有在python3中才有 __mro__ 和 mor() 方法。

 

(四)多继承中super本质

不是直接查找父类,而是根据调用节点的广度优先顺序执行的。

下面看一个例子:

创建ABCD类,D类继承B,C类,B类继承A类,C类继承A类。

在每个方法中都调用super().func()方法,查看执行顺序。

解析:d.func一开始执行,就找MRO列表【D、B、C、A】中前面的类D,在D中遇到super.func()时就找D的父类(有B和C,选哪个?),规定就是按照MRO列表【D、B、C、A】, 所以查B再查C,B和C都有super().func,继续找A,最后A-->C-->B-->D

进行方法返回就好了。

猜你喜欢

转载自blog.csdn.net/sinat_38068807/article/details/86498814
今日推荐