fbpx
今天要來介紹的Python繼承(Inheritance)在物件導向設計中非常的重要,使用得當可以提高我們程式碼的重用性(Reusable)及維護性。
繼承(Inheritance)顧名思義,就是會有父類別(或稱基底類別Base Class)及子類別(Sub Class)的階層關係。子類別會擁有父類別公開的屬性(Attribute)及方法(Method)。
所以Python繼承(Inheritance)的概念就是將各類別(Class)會共同使用的屬性(Attribute)或方法(Method)放在一個獨立的類別(Class)中,其它的類別(Class)透過繼承(Inheritance)的方式來擁有,降低程式碼的重複性。

 

Python繼承(Inheritance)的重要觀念如下:
  • 如何使用Python繼承(Inheritance)
  • 方法覆寫(Method Overriding)
  • 多層繼承(Multi-Level Inheritance)
  • 多重繼承(Multiple Inheritance)

一、如何使用Python繼承(Inheritance)

在實務上開發應用程式時,隨著類別(Class)的增加,可能會發現有些類別(Class)擁有共同的屬性(Attribute)或方法(Method),如下範例:

範例中的Car及Airplane類別(Class)皆擁有drive()方法,當其有數百行程式碼時,在應用程式中重複出現是不好的且違背DRY(Don’t Repeat Yourself)原則,未來這個方法(Method)有問題或邏輯改變了,就要修改好幾個地方,難於維護。

這時候就可以使用物件導向的繼承(Inheritance)設計,將共同的屬性(Attribute)或方法(Method)定義在一個類別(Class)中,而其它類別(Class)則透過繼承(Inheritance)的方式來擁有它,如下範例:

我們將Car及Airplane類別(Class)的共同方法drive()定義在一個新的Transportation類別(Class)中,並且新增一個屬性(Attribute)為color。

Transportation類別(Class)就叫父類別或基底類別(Base Class),而Car及Airplane類別(Class)就稱為子類別(Sub Class),在類別名稱的地方透過括號的方式來繼承(Inheritance),藉此擁有父類別公開的屬性(Attribute)及方法(Method),如下範例:

執行結果

可以看到Car(子類別)的物件mazda擁有Transportation(父類別)的color屬性(Attribute)及drive()方法(Method)。

淺談Python類別(Class)中有提到Python提供了isinstance()方法來判斷類別(Class)與物件(Object)之間的關係,而這邊Python也提供了issubclass()方法來判斷類別(Class)之間的關係,如下範例:
為什麼我們會說Python的所有類別(Class)皆為物件(Object)?也就是因為Python的所有類別(Class)直接或間接的繼承(Inheritance)了物件類別(object),所以我們可以看到第二個print()的結果為True。

二、方法覆寫(Method Overriding)

當子類別中定義了和父類別同名的方法(Method),這時候子類別的物件(Object)呼叫這個同名方法時,其中的實作內容將會覆蓋掉父類別的同名方法,這就叫做方法覆寫(Method Overriding),如下範例:
執行結果

這時候如果我們想在子類別中執行父類別的方法(Method)時,則可以使用super()內建方法來達成,如下範例:
執行結果

從執行結果可以看到,子類別透過super()內建方法執行父類別的drive()方法(Method)後,接著執行子類別的後續實作。

三、多層繼承(Multi-Level Inheritance)

就是繼承(Inheritance)的層級超過一層以上,如下範例:
範例中的Bird類別(Class)繼承(Inheritance)了Animal類別(Class),而Duck類別(Class)又再繼承(Inheritance)了Bird類別,形成了多層繼承(Multi-Level Inheritance)的關係。

各位有沒有發現問題?接著我們就可以建立鴨子物件(Object),並且呼叫父類別的fly()方法(Method),但是就邏輯上來說,鴨子不會飛阿~

從這邊就可以知道,雖然繼承(Inheritance)在程式碼的重用(Reusable)上非常的好,但是如果沒有適當的使用就會像此範例一樣產生邏輯上的錯誤。另外,在多層繼承(Multi-Level Inheritance)時,建議別超過兩層,否則反而會增加程式碼的複雜度及難以維護。

四、多重繼承(Multiple Inheritance)

就是子類別繼承(Inheritance)一個以上的父類別,如果沒有適當的使用同樣會產生問題,如下範例:
執行結果

我們知道鴨子既是動物也是鳥類,所以範例中Duck類別(Class)多重繼承(Multiple Inheritance)Animal及Bird類別(Class),接著我們建立duck物件(Object),並且呼叫eat()方法(Method),為什麼是執行Animal類別的eat()方法(Method)而不是Bird類別的eat()方法(Method)呢?

因為Python編譯器在執行多重繼承(Multiple Inheritance)時,會先檢查Duck類別(Class)是否有eat()方法(Method),以這個範例來說沒有,接著Python編譯器會尋找多重繼承(Multiple Inheritance)的第一個類別Animal是否擁有,有的話即執行,並且停止搜尋第二個類別。

如果未來有新的開發人員加入,把Duck類別(Class)的多重繼承類別(Multiple Inheritance)順序對掉,執行結果則變成如下:

這樣的情況對程式開發來說非常的危險,因為產生了不如預期的執行結果。

會發生這樣的問題就是因為多重繼承(Multiple Inheritance)的各類別(Class)有相同的方法(Method)。要避免此問題,就是各類別應各司其職,避免有相同的方法,如下範例,否則就會產生以上範例的問題。
從範例中可以看到,Animal和Bird類別(Class)中沒有共同的方法(Method)且有各自的行為,這時候Duck類別(Class)的多重繼承(Multiple Inheritance)就不會產生問題。

五、小結

以上就是Python物件導向的繼承(Inheritance)重要觀念教學,適當的使用會讓程式碼的重用性(Reusable)及維護性非常的好,希望看完這篇教學後,對Python繼承(Inheritance)的設計有進一步的認識。

蝦皮資深工程師來襲🤩,立即點擊圖片獲得更多資訊👆

精彩內容預告:機器學習實作(新手友善)、 Chrome Extension 擴充套件

「好文轉自古耕全–Python繼承(Inheritance)實用教學,如果你喜歡他的文章歡迎回到他的部落格看更多:)」