什麼是繼承?
繼承是物件導向中的一個重要概念。簡單來說:
子類別(子 class)可以擁有父類別的屬性(Attribute)和方法(Method),不用重新寫一遍。
就像你從父母那裏繼承了身高、髮色,甚至壞習慣(?)
在開始介紹繼承前,我們先來看一下這段程式碼:
|
|
什麼是 init( )?為什麼每個類別都有它?
你可以把 init( ) 想像成「物件的出生設定」,它會自動幫你設定這個物件的「初始狀態」,例如名稱、價格等等。物件一創出生時,這個方法就會自動被執行,設定好初始資料。
init( ) 有一個專業術語叫 “constructor (建構子”) : 這是用來初始化物件、在物件「出生」的那一刻就自動執行。
為什麼需要 constructor(建構子)?
|
|
|
|
什麼是self?
self 指的是「目前這個物件本身」。就像你在介紹自己:「我的名字是 self.name」,這樣每個物件就能記住自己的資料。
小結:
- init 是 對物件進行初始化 的特殊方法(constructor)。
- self 是 物件本身,指的是這個 class 所建立出來的物件。
介紹完了__init__和self, 我們就可以來寫繼承了:
首先,繼承的基礎寫法為 class 子(父) , 代表子繼承父的屬性及方法。
繼承 (基礎寫法):
|
|
這裡我們做了幾件事 : (1)「手動」呼叫父類別 Product 的 init( ),來初始化 name 和 price,然後再 (2) 自己新增 volume。
我們來看這一句 :
|
|
(父類別名稱).init(self,…) 這種寫法看似沒什麼問題,但會有幾個缺點:
-
如果未來父類別名稱改變,這裡也必要跟著一起改 → 維護困難。
-
若有多重繼承(萬一同時繼承多個父類別)會搞混。
為了解決上述問題,Python 提供了 super( ) 內建函式:
什麼是 super( )?
super( ) 用來從子類別中呼叫父類別的方法。super( ) 代表的是「父類別」,但不用寫死父類別的名字。
|
|
所以我們可以這樣寫
繼承 (進階寫法)
|
|
如果你未來把 Product 改名成 Item , 用 super( ) 就不需要手動修改任何東西。
小結:
當你想在「原本功能不變」的基礎上加一點自己的功能,就用 super() 把父類的東西也一起執行。
總結:
| 概念 | 解釋 |
|---|---|
| init() | 物件初始化方法(像是出生設定) |
| constructor | 建構子,負責建立物件時的初始化行為 |
| self | 指向目前的物件本身 |
| Product.init() | 明確呼叫父類別的方法(不推) |
| super().init() | 推薦方式,維護性高,更安全 |
繼承 (完整範例)
|
|
常見問題 Q&A
Q1: 為什麼要繼承?
A: 繼承可以讓我們重複使用既有的程式碼,避免每個類別都重頭寫一次。比如你定義了一個 Product 類別,之後建立 Drink、Snack 等類別時,就能直接繼承 Product 的屬性與方法,只補上各自特有的部分即可。
Q2: 一定要用 super() 嗎?
A: 沒有硬性規定,你也可以直接用 Product.__init__(self, name, price),但 super() 是更推薦的寫法,特別是後續有多重繼承時會更簡潔。
Q3: 子類別可以新增自己的方法嗎?
A: 當然可以!你可以在 Drink 裡加上任何想加的方法或屬性。
Q4: 如果子類別沒有寫 __init__ 會怎樣?
A: Python 會自動使用父類別的 __init__(),不會報錯,只是就無法加入子類別自己的新屬性了 # (1)。
|
|
Q5: 可以繼承多個父類別嗎?
A: 可以,Python 支援 多重繼承,例如:class A(B, C),但建議初學者先從單一繼承開始學起。
🤔 腦力激盪
如果你要寫一個 Student 類別,你會繼承 Person 還是 Teenager?為什麼?
(參考答案)
-
初階想法: 我會繼承 Teenager,因為大多數學生是青少年,而 Teenager 裡的屬性像「打工」或「升學壓力」也適用,直接用比較方便。
-
進階想法: 如果我的 Student 類別要包含國小、國中、高中、研究所,那就不適合只繼承 Teenager,應該回頭繼承 Person,再自己定義年齡區段或學級屬性。
感謝閱讀這篇簡單實用的繼承入門指南,希望你有更熟悉 class 的應用!~