Python 多型(Polymorphism):為什麼相同的方法可以有不同的行為?
Python 物件導向程式設計系列(三)|Class × Inheritance × Polymorphism × AI 協作學習
Python 實習物件導向智慧養殖AI 協作前面我們學過類別(Class)與繼承(Inheritance)。類別幫助我們組織資料與行為;繼承讓不同類別共用既有功能。接下來要學習另一個重要觀念:多型(Polymorphism)。
一、從生活情境理解多型
如果你對學生與老師都說「請介紹自己」,學生可能說「我正在學 Python」,老師可能說「我教授 Python」。相同的指令,因對象不同而產生不同的回應。
class Student:
def introduce(self):
print("我是學生,正在學習 Python")
class Teacher:
def introduce(self):
print("我是老師,負責教授 Python")
student = Student()
teacher = Teacher()
student.introduce()
teacher.introduce()
我是學生,正在學習 Python
我是老師,負責教授 Python兩個類別都具有 introduce() 方法,但實際執行內容不同。這也說明:Python 的多型不一定需要繼承。
二、水井村智慧養殖池:同一個方法,不同行為
假設有三種養殖池:一般養殖池顯示溶氧;智慧養殖池判斷異常;AI 智慧養殖池提供管理建議。它們都可以使用 check_status(),但執行內容不同。
三、建立父類別 Pond
class Pond:
def __init__(self, name, oxygen):
self.name = name
self.oxygen = oxygen
def check_status(self):
return f"{self.name}:溶氧 {self.oxygen}"父類別提供所有養殖池共通的資料與方法。
四、使用繼承與方法覆寫實現多型
class SmartPond(Pond):
def check_status(self):
if self.oxygen < 5:
return f"{self.name}:溶氧偏低"
return f"{self.name}:溶氧正常"
class AIPond(Pond):
def check_status(self):
if self.oxygen < 5:
return f"{self.name}:建議檢查增氧設備"
return f"{self.name}:目前環境正常"子類別重新定義父類別原有的 check_status(),稱為方法覆寫(Method Overriding)。注意:此處的 AIPond 只是規則式建議,尚未連接真正的 AI 模型。
五、同一個 for 迴圈管理不同物件
ponds = [
Pond("一號池", 5.8),
SmartPond("二號池", 4.2),
AIPond("三號池", 4.3)
]
for pond in ponds:
print(pond.check_status())一號池:溶氧 5.8
二號池:溶氧偏低
三號池:建議檢查增氧設備這段程式不需要判斷每個物件是哪個類別。Python 會根據物件的實際類型,選擇對應的方法。這種行為也稱為動態派送(Dynamic Dispatch)。
六、新增魚菜共生養殖池,原本迴圈不必修改
class AquaponicsPond(Pond):
def __init__(self, name, oxygen, water_level):
super().__init__(name, oxygen)
self.water_level = water_level
def check_status(self):
if self.water_level < 30:
return f"{self.name}:水位偏低"
if self.oxygen < 5:
return f"{self.name}:溶氧偏低"
return f"{self.name}:系統正常"
ponds.append(AquaponicsPond("四號池", 5.6, 25))
for pond in ponds:
print(pond.check_status())一號池:溶氧 5.8
二號池:溶氧偏低
三號池:建議檢查增氧設備
四號池:水位偏低新增類別後,原本的迴圈仍然可以使用,這是多型對軟體擴充的重要價值。以上警戒值僅供教學,實際系統須依養殖物種與設備設定。
七、多型一定要有繼承嗎?
不一定。Python 有鴨子型別(Duck Typing)的特性:只要物件提供程式需要的方法,就能以相同方式使用。
class Dog:
def speak(self):
return "汪汪"
class Cat:
def speak(self):
return "喵喵"
animals = [Dog(), Cat()]
for animal in animals:
print(animal.speak())汪汪
喵喵Dog 和 Cat 沒有共同的自訂父類別,卻都能回應 speak()。
八、Class、Inheritance、Polymorphism 比較
| 觀念 | 核心問題 | 養殖池範例 |
|---|---|---|
| Class 類別 | 如何組織資料與行為? | 建立 Pond |
| Inheritance 繼承 | 如何共用並擴充既有設計? | SmartPond(Pond) |
| Polymorphism 多型 | 如何以相同方式操作不同物件? | check_status() |
九、AI 時代的多型實習挑戰
No-AI:先預測
不使用 AI,閱讀三種養殖池程式,預測執行結果,並說明為何相同的 check_status() 會有不同輸出。
AI Pair:比較設計
請 AI 寫出兩種版本:一種以 if/elif 判斷類別,一種使用多型。比較新增養殖池時需要修改哪些程式。
Challenge AI:擴充系統
新增 ShrimpPond 類別,提供專屬狀態檢查功能,卻不能修改原本的 for 迴圈。
建議提示詞:
十、結語:AI 會寫多型,但你知道何時需要嗎?
當系統只有一種養殖池時,可能不需要多型;當系統逐漸擴充,包含不同設備與監控規則時,多型就能讓程式用一致的方式操作不同物件。
沒有留言:
張貼留言