Python 速查手冊

6.10 多型

多型 (polymorphism) 是物件導向程式設計 (object-oriented programming) 中第三個重要概念,所謂多型是要讓型態有更好的適用性,像是不同型態的物件都能接收到同樣的訊息,各種型態的物件 (object) 也都能做出各自的反應,其他程式語言可能會透過繼承 (inheritance) 關係或實作介面來定義多型,導致有些人誤以為 Python 沒有多型,事實上,多型在 Python 裡頭無處不在。

Python 是用鴨子型態 (duck type) 的觀念來詮釋多型的,所謂鴨子型態來自美國作家的一句話,中文簡單講就是某個人看見一隻鳥,只要這隻鳥走起路來像鴨子,游泳像鴨子,叫聲也像鴨子,那這個人就會叫那隻鳥為鴨子,換句話說, Python 中只要有一樣的定義都可視作多型。

說這句話的美國作者是 James Whitcomb Riley ,詳見維基百科 Duck test 的介紹。

先來看到多型簡單的範例, DuckUnknown 為兩個不同的類別 (class) ,兩者定義三個相同的方法 (method) ,分別是走路 walk() 、 游泳 swim() 及發出聲音 sound()

class Duck:
    def walk(self):
        print("....")
    
    def swim(self):
        print("))((")
    
    def sound(self):
        print("呱呱")

class Unknown:
    def walk(self):
        print(".*..")
    
    def swim(self):
        print("(())")
    
    def sound(self):
        print("哇哇")

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:poly01.py
# 功能:示範定義類別
# 作者:張凱慶

把兩個類別的實體 (instance) 物件放到串列 (list) d 中,利用 for 迴圈 (loop) 可作相同的處理, DuckUnknown 就是鴨子型態的呈現, Python 用這種方式來詮釋多型的

from poly01 import Duck
from poly01 import Unknown

d = [Duck(), Unknown()]
for i in d:
    i.walk()
    i.swim()
    i.sound()

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:poly02.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 poly02.py
....
))((
呱呱
.*..
(())
哇哇
$

再來看到像是序列 (sequence) 型態都有 count() 方法, count() 回傳參數 (parameter) 在該序列裡的總數,例如變數 (variable) a 為字串 (string) "12345" ,裡頭有一個字串 "4" ,同樣的道理,變數 b 為有五個元素的串列,由於裡頭沒有字串 "4" ,因此回傳整數 0

a = "12345"
b = [1, 2, 3, 4, "5"]

print(a.count("4"))
print(b.count("4"))

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:poly03.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 poly03.py
1
0
$

此外像是類別都有預設的方法,例如前後被兩條底線包圍的 __str__() 方法,整數 11 回傳 11 的字串形式,自行定義的類別也可自訂回傳的字串型態,例如這裡 Demo() 類別的 __str__() 方法回傳字串 "Demo"

class Demo:
    def __str__(self):
        return "Demo"

print(Demo())

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:poly04.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 poly4.py
Demo
$

上一頁: 6.9 多重繼承
Python 速查手冊 - 目錄
下一頁: 6.11 __del__()
回 Python 教材首頁