クラス

【Python】クラスの継承の基本

【Python】クラスの継承の基本

Pythonのクラスの継承の基本について解説します。

クラスの継承

クラスの継承(Inheritance)は、既存クラスのインスタンス変数やメソッドを引き継ぎ、新しい変数やメソッドを追加・上書きする仕組みです。継承元のクラスを基底クラス(スーパークラス/親クラス)、継承先を派生クラス(サブクラス/子クラス)と呼びます。

例えば、Personクラスを継承して、Teacherクラスを作る場合を考えてみましょう。

Python クラスの継承

Personクラスを基底クラス、Teacherクラスを派生クラスとして定義すると、TeacherクラスはPersonクラスの変数やメソッドを引き継ぎ、さらにsubject変数やmyworkメソッドを追加できます。これにより、共通のコードを再定義する必要がなくなり、再利用性が向上します。

この記事では、Pythonにおけるクラス継承の基本について説明します。

Pythonでのクラス継承

以下に、PersonクラスとTeacherクラスの継承例を示します。

class Person:
    """人間クラス"""

    def __init__(self, first_name=None, last_name=None):
        self.first_name = first_name
        self.last_name = last_name

    def say_myname(self):
        print(f"私の名前は、{self.last_name}{self.first_name}です。")


class Teacher(Person):
    """教師クラス"""

    def mywork(self):
        print(f"{self.last_name}{self.first_name}は教師として働いています。")


def main():
    tanaka = Teacher("太郎", "田中")
    # 親クラスのメソッドの呼び出し
    tanaka.say_myname()
    # 自分のクラスのメソッドの呼び出し
    tanaka.mywork()


if __name__ == "__main__":
    main()
【実行結果】
私の名前は、田中太郎です。
田中太郎は教師として働いています。

クラスを継承するには、上記例でclass Teacher(Person):と記載したように「class 派生クラス名(基底クラス名):」といった形式で定義します。派生クラスのメソッドは、作成したクラス内に追加していきます。

派生クラスのTeacherクラスでは、say_mynameメソッドは定義していませんが、tanaka.say_myname()のように派生クラスのインスタンスから基底クラスのメソッドを呼び出すことが可能です。

メソッドのオーバーライド

継承により派生クラスで基底クラスのメソッドが使用できますが、場合によって同じ名称のメソッドでも異なる処理をしたい場合があります。このような時には、基底クラスで定義したメソッドを派生クラスで上書きします。

このように上書きを行うことをメソッドのオーバーライドと言います。以下がメソッドのオーバーライド例です。

class Person:
    """人間クラス"""

    def __init__(self, first_name=None, last_name=None):
        self.first_name = first_name
        self.last_name = last_name

    def say_myname(self):
        print(f"私の名前は、{self.last_name}{self.first_name}です。")


class Teacher(Person):
    """教師クラス"""

    def mywork(self):
        print(f"{self.last_name}{self.first_name}は教師として働いています。")

    # メソッドのオーバーライド
    def say_myname(self):
        print(f"私は、教師の{self.last_name}{self.first_name}です。")


def main():
    tanaka = Teacher("太郎", "田中")
    tanaka.say_myname()
    tanaka.mywork()


if __name__ == "__main__":
    main()
【実行結果】
私は、教師の田中太郎です。
田中太郎は教師として働いています。

上記例では、say_mynameメソッドを派生クラスでオーバーライドすることで結果の出力を変更しています。このように必要に応じてオーバーライドでメソッドを上書きすることで、派生クラスに異なる動作をさせることができ、柔軟なカスタマイズを実現できます。

superによる基底クラスのメソッド呼び出し

派生クラスから基底クラスのメソッドを呼び出すにはsuperを使用します。

以下は、派生クラスのコンストラクタの中で基底クラスのコンストラクタを呼び出す例です。

class Person:
    """人間クラス"""

    def __init__(self, first_name=None, last_name=None):
        self.first_name = first_name
        self.last_name = last_name

    def say_myname(self):
        print(f"私の名前は、{self.last_name}{self.first_name}です。")


class Teacher(Person):
    """教師クラス"""

    def __init__(self, first_name=None, last_name=None, subject=None):
        # 親クラスのコンストラクタの呼び出し
        super().__init__(first_name, last_name)
        # 自クラスの変数初期化
        self.subject = subject

    def mywork(self):
        print(f"{self.last_name}{self.first_name}は教師として働いています。")

    def say_myname(self):
        print(f"私は、{self.subject}教師の{self.last_name}" f"{self.first_name}です。")


def main():
    tanaka = Teacher("太郎", "田中", "英語")
    tanaka.say_myname()
    tanaka.mywork()


if __name__ == "__main__":
    main()
【実行結果】
私は、英語教師の田中太郎です。
田中太郎は教師として働いています。

上記例では、コンストラクタ__init__をオーバーライドしています。この時に、通常は、first_namelast_nameの初期化についても記載する必要があります。

しかし、super().__init__(first_name, last_name)という形で基底クラスのコンストラクタを呼び出した後に、Teacherクラスで追加した変数subjectの初期化を追加することで、重複する初期化コードを排除できます。

このように基底クラスの初期化処理を再利用することで、同じ処理を複数個所で記載する必要もなくなりメンテナンス性が向上します。

まとめ

Pythonのクラスの継承の基本について解説しました。継承の際に重要になってくるメソッドのオーバーライドとsuperによる基底クラスのメソッドの呼び出しについても説明しています。

オブジェクト指向プログラミングでは、クラス継承はプログラムの再利用性を高めるために非常に重要な概念です。基本を理解して、しっかりと使いこなせるようになりましょう。