Photo by Plush Design Studio on Unsplash
今天要來介紹的Python多型(Polymorphism)在物件導向設計中非常的重要,不論是設計模式(Design Patterns)或設計原則(Design Principles),都會有多型(Polymorphism)的概念。
使用多型(Polymorphism)來設計類別架構,能夠讓程式碼的相依性不會那麼高,並且透過統一的介面來彈性擴充功能。今天主要的重點有兩個部分:
- Python抽象方法(Abstract Method)
- 多型(Polymorphism)
一、Python抽象方法(Abstract Method)
要使用抽像方法(Abstract Method)的類別首先要繼承ABC(Abstract Base Class)類別,接著在抽象方法上方加上@abstractmethod裝飾詞(Decorator),並且不會有實作內容,如下範例:
from abc import ABC, abstractmethod
# 登入類別
class Login(ABC):
@abstractmethod
def login(self):
pass
由於抽象方法(Abstract Method)是抽象的,所以只要有抽象方法(Abstract Method)的類別就稱為抽象類別,是無法建立物件的,如下範例:
from abc import ABC, abstractmethod
# 登入類別
class Login(ABC):
@abstractmethod
def login(self):
pass
user_login = Login()
執行結果
錯誤訊息顯示無法實體化含有抽象方法(Abstract Method)的抽象類別。必須透過繼承(Inheritance)的類別來進行抽象方法(Abstract Method)的實作,如下範例:
from abc import ABC, abstractmethod
# 登入抽象類別
class Login(ABC):
@abstractmethod
def login(self):
pass
# Facebook登入機制
class FacebookLogin(Login):
def login(self):
print("Facebook login implementation.")
fb = FacebookLogin()
fb.login()
執行結果
如果繼承(Inheritance)的類別(Class)沒有實作抽象類別中的抽象方法(Abstract Method),同樣視為抽象類別,也無法建立物件(Object)。範例中,FacebookLogin類別繼承(Inheritance)Login抽象類別,並且實作其login()抽象方法(Abstract Method),即可建立物件進行呼叫的動作。
所以,抽象方法(Abstract Method)通常應用於定義各類別的共同介面,讓未來要增加的需求功能,必須遵守共同的規則進行實作,來達到各類別擁有一致性的介面,不但好維護且易於擴充。
二、多型(Polymorphism)
顧名思義,就是同一個介面或方法(Method)可以有多個實作型態。
我們來延伸上面的例子,如果今天應用程式要增加Google及Twitter的登入機制,想必大家應該知道要怎麼做了吧,就是建立各自的類別(Class)繼承(Inheritance)Login抽象類別,接著實作其中的login抽象方法(Abstract Method),如下範例:
我們來延伸上面的例子,如果今天應用程式要增加Google及Twitter的登入機制,想必大家應該知道要怎麼做了吧,就是建立各自的類別(Class)繼承(Inheritance)Login抽象類別,接著實作其中的login抽象方法(Abstract Method),如下範例:
from abc import ABC, abstractmethod
# 登入抽象類別
class Login(ABC):
@abstractmethod
def login(self):
pass
# Facebook登入機制
class FacebookLogin(Login):
def login(self):
print("Facebook login implementation.")
#Google登入機制
class GoogleLogin(Login):
def login(self):
print("Google login implementation.")
#Twitter登入機制
class TwitterLogin(Login):
def login(self):
print("Twitter login implementation.")
fb = FacebookLogin()
fb.login()
google = GoogleLogin()
google.login()
twitter = TwitterLogin()
twitter.login()
執行結果
各位有沒有發現,來源端不同的類別物件(Object)呼叫同樣的方法(Method)時,卻可以有不同的實作方式,這也就是所謂的多型(Polymorphism)。
其中的原理,就是Python編譯器在執行期間(Runtime)看到三個實體類別(Class)皆繼承(Inheritance)了Login抽象類別,接著在物件(Object)呼叫login()方法(Method)時,Python編譯器則依據呼叫物件(Object)的實體類別(Class)來執行相應的類別實作。
另外,在Python繼承(Inheritance)實用教學中有提到方法覆寫(Method Overriding)的概念,其實就是多型(Polymorphism)的展現,如下範例:
# 交通工具(基底類別)
class Transportation:
# 駕駛方法
def drive(self):
print("Base class drive method is called.")
# 汽車子類別
class Car(Transportation):
# 駕駛方法
def drive(self):
print("Car drive method is called.")
# 飛機類別
class Airplane(Transportation):
# 駕駛方法
def drive(self):
print("Airplane drive method is called.")
mazda = Car()
mazda.drive()
airplane = Airplane()
airplane.drive()
執行結果
同樣可以看到來源端不同的類別物件(Object)呼叫同一個方法(Method),而有不一樣的實作。
就是由於子類別(Sub Class)都覆寫(Method Overriding)了父類別(Base Class)的drive()共同方法(Method),使得Python編譯器在執行期間(Runtime),則依據呼叫端物件(Object)的實體類別(Class)來決定要執行哪一個子類別(Sub Class)的實作內容。
使用多型(Polymorphism)最大的優點就是易於擴充及降低類別間的相依性。從這兩個例子可以看到,不論未來要再增加新的登入機制或交通工具,都能非常容易的透過新增類別來進行擴充,並且有一致性的介面。
也由於各類別依據共同介面來各自實作,所以類別間的相依性降低,在新增需求功能時,不用擔心會影響到其他類別的實作。
也由於各類別依據共同介面來各自實作,所以類別間的相依性降低,在新增需求功能時,不用擔心會影響到其他類別的實作。
三、小結
以上就是Python抽象方法(Abstract Method)及物件導向的多型(Polymorphism)概念,希望看完這篇教學後,能夠設計出有彈性的架構來面對實務上各種千變萬化的需求。
有句話說:開發是一時的,維護是一輩子的,擁有易擴充且好維護的架構非常重要,Python的繼承(Inheritance)讓程式碼的重用性(Reusable)提高,而多型(Polymorphism)概念則讓各類別有一致性的介面,易於擴充及維護。
有句話說:開發是一時的,維護是一輩子的,擁有易擴充且好維護的架構非常重要,Python的繼承(Inheritance)讓程式碼的重用性(Reusable)提高,而多型(Polymorphism)概念則讓各類別有一致性的介面,易於擴充及維護。
感謝教學
回覆刪除網誌管理員已經移除這則留言。
回覆刪除您好,請別在留言處打廣告唷,謝謝 :)
刪除好像沒有說到多型的優點
回覆刪除