Python Object-oriented Programming -4 Polymorphism

Young Chen
宅男雜誌
Published in
4 min readFeb 9, 2020

再談多型(Polymorphism)

第一篇一樣地已經談過關於多型的定義,回顧定義:

多型(Polymorphism): 單一介面操作多種型態的物件不同形態的物件可以定義相同的介面但不同行為。可以簡單講:定義名稱相同的方法,傳入不同參數(訊息)會執行不同行為

ok…真的不可能看完就懂

在想想貓狗例子吧:想想貓狗共同行為,我們假設貓狗都會說話(speak),但是可以一個speak各自表述,各叫各的,因此程式碼可以這樣表示:

class Dog():

def __init__(self, name):

self.name = name

def speak(self):
return self.name + " says woof!"
class Cat():

def __init__(self, name):

self.name = name

def speak(self):
return self.name + " says meow!"
貓狗類別又定義好呢!

以上皆定義了speak()方法並且各自表述,那麼如何能夠表現初此種特性的方便之處?根據定義,我們需要一個單一介面操作,定義相同介面但是要不同行為,因此嘗試這樣建立一個類似統一介面概念的方法:

def pet_speak(pet):
print(pet.speak())

然後,初始化一下阿貓阿狗:

winnie = Dog(‘Winnie’)
young = Cat(‘Young’)

讓他們各自表述一下:

pet_speak(winnie)
pet_speak(young)
# Winnie says woof!
# Young says meow!

神奇地是,這樣的做法允許了同樣使用pet_speak(),只因傳入的object不同而有不同的行為,各自叫他們自己的。這在設計上允許了更大的彈性,再來我們可以持續結合前面繼承的例子,將繼承與多型一併使用:

class Animal():

def __init__(self, name):

self.name = name

def speak(self):
raise NotImplementedError("Subclass must be implement this abstract class")

speak() 定義於Animal這父類別這寫法有那麼一點點抽象方法(abstract method)的味道(不完全是,Python有提供合適的做法),這寫法其實只是防止初始化Animal後直接叫用此方法。從此得知這樣設計是預期子類別Dog, Cat各自實作speak()

class Dog(Animal):

def speak(self):
return self.name + " says wolf!"

class Cat(Animal):

def speak(self):
return self.name + " says meow!"
young = Cat('young')
young.speak()
# 'young says meow!'
winnie = Dog('winnie')
winnie.speak()
# 'winnie says wolf!'

突然之間我好像悟了什麼…為何跟沒有共識的92共識87%像?我是不是知道太多了?

先生先生…查水表囉趕快出來!

--

--

Young Chen
宅男雜誌

曾經是全端工程師,目前在資料科學團隊中主要負責雲端架構相關工作,透過自學正在資料科學領域相關知識耕耘中。mail: chiyoung0307@gmail.com