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