継承とポリモーフィズムの設計

Python によるオブジェクト指向プログラミング

Alex Yarosh

Content Quality Analyst @ DataCamp

ポリモーフィズム

 

 

統一インターフェースで異なるクラスのオブジェクトを操作

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 によるオブジェクト指向プログラミング

リスコフの置換原則

 

基底クラスは、プログラムの性質を変えずに任意のサブクラスと置換可能であるべき

BankAccount が動く場所では、CheckingAccount も動くべき

バーバラ・リスコフの写真

Python によるオブジェクト指向プログラミング

リスコフの置換原則

 

基底クラスは、プログラムの性質を変えずに任意のサブクラスと置換可能であるべき

構文上
  • 関数シグネチャが互換
    • 引数、戻り値
意味上
  • オブジェクトとプログラムの状態が一貫
    • サブクラスは入力条件を強化しない
    • サブクラスは出力条件を弱めない
    • 例外を追加しない
Python によるオブジェクト指向プログラミング

LSP 違反の例

構文の非互換

BankAccount.withdraw() は引数1つ、CheckingAccount.withdraw() は2つを要求

サブクラスが入力条件を強化

BankAccount.withdraw() は任意額を受け付けるが、CheckingAccount.withdraw() は金額に制限を仮定

サブクラスが出力条件を弱める

BankAccount.withdraw() は残高を正に保つかエラー、CheckingAccount.withdraw() は残高を負にし得る

Python によるオブジェクト指向プログラミング

LSP 違反の例

→ サブクラスのメソッドで追加の属性を変更

→ サブクラスのメソッドで例外を追加して送出

Python によるオブジェクト指向プログラミング

 

 

 

 

$$\text{\textbf{\Huge{LSPなし=継承なし}}}$$

Python によるオブジェクト指向プログラミング

Let's practice!

Python によるオブジェクト指向プログラミング

Preparing Video For Download...