day24 03 多繼承

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 

相關文章
相關標籤/搜索