為繼承與多型而設計

Python 物件導向程式設計

Alex Yarosh

Content Quality Analyst @ DataCamp

多型(Polymorphism)

 

 

使用統一介面操作不同類別的物件

Python 物件導向程式設計

帳戶類別層級

Python 物件導向程式設計

介面才是關鍵

# Withdraw amount from each of accounts in list_of_accounts
def batch_withdraw(list_of_accounts, amount):
   for acct in list_of_accounts:
      acct.withdraw(amount)

b, c, s = BankAccount(1000), CheckingAccount(2000), SavingsAccount(3000) batch_withdraw([b,c,s]) # <-- Will use BankAccount.withdraw(), # then CheckingAccount.withdraw(), # then SavingsAccount.withdraw()
  • batch_withdraw() 不需檢查物件型別就知道要呼叫哪個 withdraw()
Python 物件導向程式設計

Liskov 替代原則

 

基底類別應可與其任何子類別互換,而不改變程式的任何性質

只要 BankAccount 可行,CheckingAccount 也應可行

Barbara Liskov 照片

Python 物件導向程式設計

Liskov 替代原則

 

基底類別應可與其任何子類別互換,而不改變程式的任何性質

語法面
  • 函式簽章需相容
    • 參數、回傳值
語意面
  • 物件與程式的狀態保持一致
    • 子類別方法不應加強輸入條件
    • 子類別方法不應削弱輸出條件
    • 不得新增額外例外
Python 物件導向程式設計

違反 LSP 的情況

語法不相容

BankAccount.withdraw() 需要 1 個參數,但 CheckingAccount.withdraw() 需要 2 個

子類別加強輸入條件

BankAccount.withdraw() 接受任意金額,但 CheckingAccount.withdraw() 假設金額受限

子類別削弱輸出條件

BankAccount.withdraw() 只能留下正餘額或拋出錯誤,CheckingAccount.withdraw() 可能留下負餘額

Python 物件導向程式設計

違反 LSP 的情況

→ 在子類別方法中變更額外屬性

→ 在子類別方法中額外拋出例外

Python 物件導向程式設計

 

 

 

 

$$\text{\textbf{\Huge{無 LSP——就無繼承}}}$$

Python 物件導向程式設計

一起來練習吧!

Python 物件導向程式設計

Preparing Video For Download...