1 class ShenXian: # 神仙 2 3 def fei(self): 4 print("神仙都會⻜") 5 6 class Monkey: # 猴 7 8 def chitao(self): 9 print("猴⼦喜歡吃桃⼦") 10 11 class SunWukong(ShenXi ...
# 多繼承:
# 在繼承關係中.⼦類自動擁有⽗類中除私有屬性外其他所有內容.python⽀持多繼承.子類可擁有多⽗類.
1 class ShenXian: # 神仙 2 3 def fei(self): 4 print("神仙都會⻜") 5 6 class Monkey: # 猴 7 8 def chitao(self): 9 print("猴⼦喜歡吃桃⼦") 10 11 class SunWukong(ShenXian, Monkey): # 孫悟空是神仙, 同時也是⼀只猴(自己有先自己,然後靠最近的,再其他) 12 pass 13 14 # sxz = SunWukong() # 孫悟空 15 # sxz.chitao() # 會吃桃⼦ 16 # sxz.fei() # 會⻜ 17 18 # 這就是多繼承,但當兩個⽗類中出現了重名⽅法的時候.就涉及到如何查找⽗類⽅法的問題. 19 # 即下麵的 MRO(method resolution order) 問題View Code
# 經典類MRO演算法
# 在python2.2之前用,現已棄用(做面試題參考) 採用的樹形結構的深度遞歸遍歷
# 方法:從頭開始.從左往右,一條道跑到底,然後回頭.繼續⼀條路跑到頭.(畫圖)
1 # 畫圖排順序 現用python版本已無法驗證 2 class A: 3 pass 4 class B(A): 5 pass 6 class C(A): 7 pass 8 class D(B, C): 9 pass 10 class E: 11 pass 12 class F(D, E): 13 pass 14 class G(F, D): 15 pass 16 class H: 17 pass 18 class Foo(H, G): 19 pass 20 21 # 結果 : FOO--H--G--F--D--B--A--C--EView Code
# 新式類MRO演算法(C3)
# 先拆後合 從下向上合併,拿出每一項的頭和後一項的身體進行比較.
# 如果出現了就過,從後一項的頭繼續去比較.如果不出現就出來放到結果。
# (註意:每次都是拿 頭一項 的頭和後面的身體比較,出現了就過,這時把後一項的頭作為頭一項繼續去比較,
# 若後一項的頭在後面身體還有,繼續這個操作...直到後面身體沒有再返回前面的頭,理解成一個迴圈)
1 class A: 2 pass 3 class B(A): 4 pass 5 class C(A): 6 pass 7 class D(B, C): 8 pass 9 class E(C, A): 10 pass 11 class F(D, E): 12 pass 13 class M(F, E): 14 pass 15 class N: 16 pass 17 class P(M,N): 18 pass 19 class G(P): 20 pass 21 class O: 22 pass 23 class X(O): 24 pass 25 class H(G, X, F): 26 pass 27 print(H.__mro__) 28 29 30 ''' 31 # 拆 註意別漏了末尾的 “GXF” 32 # 當類裡面只有單個繼承時不需要 33 L(H) = H + L(G) + L(X) + L(F) + GXF HGPMXFDBECANO 34 35 L(G) = G + L(P) GPMFDBECAN 36 L(X) = X + L(O) XO 37 L(F) = F + L(D) + L(E) + DE FDBECA 38 39 L(P) = P + L(M) + L(N) + MN PMFDBECAN 40 L(O) = O 41 L(D) = D + L(B) + L(C) + BC DBCA 42 L(E) = E + L(C) + L(A) + CA ECA 43 44 L(M) = M + L(F) + L(E) + FE MFDBECA 45 46 L(N) = N 47 L(B) = B + L(A) BA 48 L(C) = C + L(A) CA 49 L(A) = A 50 51 52 # HGPMXFDBECANOView Code
# super:
# super是查找mro順序中的下一個
# 單繼承中我們可以認為super是對父類中的屬性或方法的引入
# super()常用地方:
# 1.訪問⽗類的構造⽅法
# 2.⼦類⽅法調⽤⽗類(MRO)中的⽅法
1 # 訪問⽗類的構造⽅法 2 class Foo1: 3 def __init__(self, a, b, c): 4 self.a = a 5 self.b = b 6 self.c = c 7 class Bar(Foo1): 8 def __init__(self, a, b, c, d): 9 super().__init__(a, b, c) # 訪問⽗類的構造⽅法 對父類中的屬性引入 10 self.d = d 11 12 b = Bar(1, 2, 3, 4) 13 print(b.__dict__) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}View Code
1 # 當⼦類⽅法想調⽤⽗類(MRO)⽅法 2 class ShengWu: 3 def dong(self): # 實例方法 4 print(self) 5 print("我是生物") 6 7 class Animal(ShengWu): 8 pass 9 10 class Cat(Animal): 11 def dong(self): # 子類中出現了和父類重名的內容. 表示對父類的方法的覆蓋(重寫). 12 super(Animal, self).dong() # 定位到Animal. 找Animal的下一個 13 # super(類, 對象).方法() 找MRO中的類. 找這個類的下一個. 去執行方法 14 print("我的貓也會動") 15 16 # self 依然是誰調用就是誰 17 # 找MRO中的下一個 18 # Cat -> Animal -> ShengWu ->Object 19 20 c = Cat() 21 print(c) 22 c.dong()View Code
# 總結 不管super()寫在哪⼉.在哪⼉執⾏.⼀定先找MRO列表.根據MRO列表的順序往下找.否則⼀切都是錯的