【授業レポート】システム開発入門 第19週目:Pythonの継承とポリモーフィズム

boy in green shirt
Photo by CDC on Pexels.com

システム開発入門の第19週目では、Pythonを使って継承とポリモーフィズムを学びました。

前回のクラスとインスタンスの学習を土台に、共通部分をまとめる方法と、同じ呼び出し方のまま振る舞いを変える方法をコードで確かめた授業です。

「似ているけれど少し違う」をどう表すか

授業の導入では、犬と猫はどちらも動物ですが、鳴き声は異なるという例を使いました。

共通する性質をAnimalに置き、異なる振る舞いをDogとCatに持たせると、三つの用語の関係を整理できます。

  • 継承:親クラスが持つ処理を、子クラスが受け継いで利用する仕組みです。
  • オーバーライド:親クラスと同じ名前のメソッドを子クラスに定義し、その振る舞いを置き換えることです。
  • ポリモーフィズム:同じ名前のメソッドを呼び出しても、対象のクラスに応じて異なる処理が動く性質です。

継承で共通する処理を親クラスに置く

最初の実習では、親クラスのAnimalと、それを継承するDog、Catを作りました。

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print(self.name + "は何かをしゃべろうとしている…")


class Dog(Animal):
    def speak(self):
        print(self.name + ":ワンワン!")


class Cat(Animal):
    def speak(self):
        print(self.name + ":ニャー!")

Animalの__init__()は、受け取った名前をself.nameに保存します。

この例ではDogとCatが独自の__init__()を持たないため、親クラスの処理を使って名前を設定できます。

一方、鳴き方はクラスごとに異なるため、二つの子クラスはspeak()をオーバーライドしています。

授業中には、生徒から「DogとCatには名前の処理を書かなくてよい」と気づく声が上がりました。

同じspeakメソッドで異なる結果を得る

次の実習では、異なるクラスのインスタンスを一つのリストに入れ、同じspeak()を順番に呼び出しました。

animals = [Dog("ポチ"), Cat("ミケ"), Animal("???")]

for animal in animals:
    animal.speak()
speak()を呼び出したときの動き
インスタンス 使われるメソッド 表示内容
Dog("ポチ") Dog.speak() ポチ:ワンワン!
Cat("ミケ") Cat.speak() ミケ:ニャー!
Animal("???") Animal.speak() ???は何かをしゃべろうとしている…

ループ側にある呼び出しは、どの要素でもanimal.speak()の一行です。

それでも各インスタンスのクラスに応じたメソッドが使われるため、呼び出す側はクラスごとの分岐を書かずに処理できます。

生徒は、この「同じ名前で呼べる」点がコードを簡潔にすることを実行結果から確認しました。

身近な題材をクラスに分ける実習

後半は、身近な題材から親クラスと子クラスを考え、継承とポリモーフィズムを実装しました。

授業で扱った題材

  • GameCharacterを親クラスにし、Warrior、Wizard、Healerで攻撃方法を変える。
  • Questionを親クラスにし、YesNoQuestionとMultipleChoiceQuestionで表示や採点方法を変える。
  • Vehicleを親クラスにし、Car、Bicycle、Trainで移動方法や速度計算を変える。

生徒は、出題方法や攻撃方法など、子クラスごとに変えたい処理をオーバーライドしました。

継承を使う前に整理すること

継承を増やせば、必ず拡張しやすくなるわけではありません。

先生は「本当に共通か」を考えずに継承すると、設計が複雑になると説明しました。

  1. 複数のクラスで共通する状態や処理を見つける。
  2. 違いとして残す処理を決める。
  3. その違いを、同じ名前のメソッドで表せるか確認する。

この順序で整理すると、親クラスに置く部分と、子クラスでオーバーライドする部分を切り分けやすくなります。

第19週目で確認したこと

  • 共通する名前の処理は、親クラスにまとめて子クラスから利用できる。
  • 異なる振る舞いは、子クラスで同じ名前のメソッドをオーバーライドして表せる。
  • ポリモーフィズムを使うと、呼び出す側の書き方をそろえたまま、クラスごとの処理を実行できる。
  • 継承関係を作る前に、共通部分と異なる部分を分けて考える必要がある。

次回は、第20週目のオブジェクト指向ミニプロジェクトで、クラス設計図を描き、継承とポリモーフィズムを使った実装とテストに進みます。

この記事に関連する株式会社greedenの取り組み

株式会社greedenは、要件定義から設計、実装、テスト、保守まで一気通貫でWebシステム開発を支援しています。継承を含む設計を、将来の機能追加や運用まで見据えて相談したい場合は、開発支援をご覧ください。

投稿者 greeden

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)