day24 03 多继承python
正常的代码中 单继承==减小了代码的重复python2.7
继承表达的是一种 子类是父类的关系函数
一、简单的多继承关系spa
A,B,C,D四个类,其中D类继承A,B,C三个父类,所以也叫多继承,子类方法调用的时候先找本身里面的,没有再根据就近原则逐个找父类里面的,最后没有仍是会报错code
class A: def func(self): print('A') class B: def func(self): print('B') class C: def func(self): print('C') class D(A,B,C): # D继承A,B,C三个类,因此叫多继承 def func(self): print('D') d = D() d.func() # 首先找本身里面是否有func方法,有就用本身的,没有才找父类,而且找的时候的顺序:A,B,C---就近原则
因为D类本身里面就有func方法,因此直接用本身的,因此运行结果:blog
D
这样简单的多继承问题,遵循的原则是:就近原则,按照D>A>B>C的顺序找继承
二、钻石继承问题class
钻石继承关系:有四个类A,B,C,D,其中B,C都继承A,而后D继承B和Cobject
class A: def func(self):print('A') # (4)若是A里面仍是找不到func函数,则会报错 class B(A): def func(self):print('B') # (2)若是B里面也没有func函数,才会找到C里面的 class C(A): def func(self):print('C') # (3)若是C里面仍是找不到func函数,则最后才会找到A的 class D(B,C): def func(self):print('D') # (1)首先先找本身自己的,若是这里没有func函数,就会根据就近原则找到B的 d = D() d.func() # 首先找本身里面是否有func方法,有就用本身的,没有才找父类
砖石继承问题,遵循的通常规则:方法
自身优先;随后就近原则(广度优先),从左往右;最后到深度,竖直写的
由于原本就知道了B和C均可以最后找到A,因此才会先D>B>C>A,若是是按照D>B>A的顺序,则不会再去找C里面的了,这样若是A里面没有,
可是C里面有须要调用的方法,就会找不到最后报错
三、漏斗形继承问题
漏斗形继承关系:有五个类:A,B,C,D,E,其中D继承B和C,B继承A,C继承E
class A: def func(self):print('A') # (3)若是A里面仍是找不到func函数,才会找到C class E: def func(self): print('E') # (5)若是E里面仍是没有,则会报错 class B(A): def func(self):print('B') # (2)若是B里面也没有func函数,就会找到A里面的 class C(E): def func(self):print('C') # (4)若是C里面仍是找不到func函数,则最后才会找到E的 class D(B,C): def func(self):print('D') # (1)首先先找本身自己的,若是这里没有func函数,就会根据就近原则找到B的 d = D() d.func() # 首先找本身里面是否有func方法,有就用本身的,没有才找父类
漏斗形继承问题,遵循的通常规则:
自身优先;而后就近原则,广度优先,可是因为B和C继承的是不一样的父类,因此先按D>B>A的顺序;
若是在A里面仍是找不到相关的方法,才会找到C>E,最后E里面没有就会报错
若是在B里面没有找到的时候就去找C里面,则会错过了A,若是最后在E里面没有找到调用的方法,可是在A里面就有,这样就会找不到而且报错了
四、乌龟形继承问题
乌龟形继承关系:有A,B,C,D,E,F六个类,其中D继承B和C,B继承A,A继承F,C继承E,E继承F
class F: def func(self):print('F') # (6)若是F里面仍是找不到func函数,才会找到C class E(F): def func(self): print('E') # (5)若是E里面仍是没有,则最后会找到F里面的若是仍是找不到则会报错 class A(F): def func(self): print('A') # (3)若是A里面仍是找不到func函数,才会找到C class B(A): def func(self):print('B') # (2)若是B里面也没有func函数,就会找到A里面的 class C(E): def func(self):print('C') # (4)若是C里面仍是找不到func函数,则会找到E的 class D(B,C): def func(self):print('D') # (1)首先先找本身自己的,若是这里没有func函数,就会根据就近原则找到B的 d = D() d.func() # 首先找本身里面是否有func方法,有就用本身的,没有才找父类
乌龟形继承问题,通常遵循的原则:
自身优先,找不到找父类;根据广度优先即就近原则先找B的,若是B里面没有则会找A的,而不是找C的,这里和前面的漏斗形问题同样的道理;
若是A里面也找不到则会找到C,而不是F里面的,这里和前面的砖石形问题同样的道理,由于A和E都会找到F;
若是在A没有找到的状况下,就会接着按照C>E>F的顺序找
五、mro()函数
执行如下代码,最后print(D.mro()),能够找到继承的顺序
class F: def func(self):print('F') # (6)若是F里面仍是找不到func函数,才会找到C class E(F): def func(self): print('E') # (5)若是E里面仍是没有,则最后会找到F里面的若是仍是找不到则会报错 class A(F): def func(self): print('A') # (3)若是A里面仍是找不到func函数,才会找到C class B(A): def func(self):print('B') # (2)若是B里面也没有func函数,就会找到A里面的 class C(E): def func(self):print('C') # (4)若是C里面仍是找不到func函数,则会找到E的 class D(B,C): def func(self):print('D') # (1)首先先找本身自己的,若是这里没有func函数,就会根据就近原则找到B的 d = D() d.func() # 首先找本身里面是否有func方法,有就用本身的,没有才找父类 print(D.mro())
运行结果:
D [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.F'>, <class 'object'>]
六、总结
新式类(继承object类的才是新式类)继承原则:广度优先(就近原则)
经典类(若是直接建立一个类在2.7中就是经典类)继承原则:深度优先,一条线从下往上找,走到底,而后再换另外一条线,走过的路就不会再走
多继承,子类的调用方法,默认就近原则
经典类中,深度优先
新式类中,广度优先
python2.7中新式类和经典类共存,新式类要继承object
python3中只有新式类,默认继承object