10.1 從多個類別繼承
多重繼承 在 Python 中允許類別從超過一個父類別繼承屬性和方法。這帶來了更大的靈活性,讓代碼重複使用,但也可能導致複雜的層次結構和潛在的衝突。
可以列出自己的類別五個父類別,大大擴展了你的可能性,使編寫代碼非常方便。實現起來很簡單——只需在類別名稱後面用逗號列出父類別:
class Base1:
def method1(self):
print("Method1 from Base1")
class Base2:
def method2(self):
print("Method2 from Base2")
class Derived(Base1, Base2):
pass
obj = Derived()
obj.method1()
obj.method2()
一切都如預期般工作——簡直太美了。
但是多重繼承有一些複雜的方面,需要在使用時考慮。我們來看看它是如何工作的,以及如何避免與多重繼承相關的問題。
10.2 呼叫幾個基礎類別都有的方法
類別可以從多個在類別名稱後面的括號中列出的父類別繼承屬性和方法。這些屬性和方法可能擁有相同的名稱:
class Base1:
def method(self):
print("Method from Base1")
class Base2:
def method(self):
print("Method from Base2")
class Derived(Base1, Base2):
pass
obj = Derived()
obj.method() # 這裡會執行哪個方法呢?
在此示例中 Derived 類別繼承自 Base1 和 Base2。當呼叫 method() 時,Python 會選擇第一個指定類別的方——Base1。
但是這不太明顯,對吧?如果有人更改基礎類別的代碼,整個應用程序的邏輯可能會受損,你甚至不知道出現了什麼問題。只會開始呼叫不太正確的方法 :)
10.3 使用 super() 和多重繼承
另一個有趣的特性是呼叫 super() 用於多重繼承的基礎類別。
例如:
class Base1:
def method(self):
print("Method from Base1")
super().method()
class Base2:
def method(self):
print("Method from Base2")
super().method()
class Derived(Base1, Base2):
def method(self):
print("Method from Derived")
super().method()
obj = Derived()
obj.method()
結果會是什麼呢?
Method from Derived
Method from Base1
或
Method from Derived
Method from Base2
我有個驚喜給你——結果會是這樣的:
Method from Derived
Method from Base1
Method from Base2
代碼 super().method() 會呼叫每個基礎類別的 method()。這正是我第一次提到多重繼承時說過的那些細節。
10.4 鑽石形 (Diamond) 繼承
最後,經典的鑽石形繼承問題。比起描述,用一個例子更容易展示:
用代碼的形式,它可能看起來像這樣:
class A:
def method(self):
print("Method from A")
class B(A):
def method(self):
print("Method from B")
super().method()
class C(A):
def method(self):
print("Method from C")
super().method()
class D(B, C):
def method(self):
print("Method from D")
super().method()
obj = D()
obj.method()
結果會是這樣的:
Method from D
Method from B
Method from C
Method from A
若要在多重繼承中不迷路,你需要很好地理解 Python 在父類別中搜索字段和方法的順序。下一講中你將會學到這個。
GO TO FULL VERSION