クラス

【Python】ポリモーフィズムと抽象クラス、抽象メソッド

【Python】ポリモーフィズムと抽象クラス、抽象メソッド

Pythonでのポリモーフィズムと抽象クラス、抽象メソッドの扱いについて解説します。

ポリモーフィズム(polymorphism)

クラス実装において、異なるクラスが共通のインターフェース(メソッドやプロパティ)を実装し、同じメソッド名で異なる振る舞いをすることをポリモーフィズム(多様性・多相性)と言います。

例として、Personクラスを継承したTeacherクラスとDoctorクラスを考えてみます。

python ポリモーフィズム

myworkメソッドは、仕事の内容を出力するメソッドです。しかし、同じmyworkメソッドであっても、Teacherクラスでは教える仕事、Doctorクラスでは診察する仕事であることを説明するように出力の振る舞いを変えたいとします。

このような際には、メソッドのオーバーライドを行います。オーバーライドについては「クラスの継承の基本」を参考にしてください。オーバーライドは、任意でメソッドの挙動を変更する仕組みですが、派生クラスでメソッドの実装を強制することができません。

派生クラスでのメソッドの実装を強制したいような場合には「抽象クラス」「抽象メソッド」を使用します。

抽象クラス、抽象メソッド

抽象クラスはインスタンス化できないクラスであり、クラス設計の構造を提供します。抽象メソッドは、その抽象クラスを継承する派生クラスが具体的に実装を行う必要があるメソッドです。

抽象クラスを継承したクラスは、抽象メソッドを実装しない限りインスタンス化することができません。抽象クラスを使うと、派生クラスは抽象メソッドを必ず実装しなければならないため、設計上の一貫性や拡張性を持たせることができます。

以降では、Pythonにおける抽象クラスと抽象メソッドの実装について説明していきます。

abcモジュールを用いた抽象クラス・抽象メソッドの実装

Pythonでは、抽象クラスと抽象メソッドを実現するためにabcモジュールが使用できます。abcとは「abstruct base class」の略です。

実装例

以下の例では、abcモジュールを使用して抽象クラス、抽象メソッドを定義しています。

import abc


class Person(abc.ABC):
    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, value):
        self.__name = value

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

    @abc.abstractmethod
    def mywork(self):
        pass


class Teacher(Person):
    def __init__(self, subject):
        self.__subject = subject

    @property
    def subject(self):
        return self.__subject

    @subject.setter
    def subject(self, value):
        self.__subject = value

    def mywork(self):
        print(f"私の仕事は、{self.__subject}の教師です。")


class Doctor(Person):
    def __init__(self, medical_speciality):
        self.__medical_speciality = medical_speciality

    @property
    def medical_speciality(self):
        return self.__medical_speciality

    @medical_speciality.setter
    def medical_speciality(self, value):
        self.__medical_speciality = value

    def mywork(self):
        print(f"私の仕事は、{self.__medical_speciality}の医者です。")


def main():
    person1 = Teacher("英語")
    person1.mywork()
    print("===")
    person2 = Doctor("内科")
    person2.mywork()


if __name__ == "__main__":
    main()
【実行結果】
私の仕事は、英語の教師です。
===
私の仕事は、内科の医者です。

上記例でのPersonクラスは、abc.ABCクラスを継承することで抽象クラスになります。myworkメソッドは、@abc.abstructmethodデコレータで付けることで抽象メソッドとなり、これによりサブクラスで必ず実装されることを要求します。

TeacherクラスとDoctorクラスはPersonを継承し、myworkメソッドをオーバーライドします。もし、Doctorクラスでmyworkメソッドの実装を忘れると、以下のようなエラーが発生します。

【実行結果例】
Traceback (most recent call last):
...(省略)...
TypeError: Can't instantiate abstract class Doctor with abstract methods mywork

このように、abcモジュールを活用することで、抽象メソッドの実装を強制し、ポリモーフィズムを実現できます。

まとめ

Pythonでのポリモーフィズムと抽象クラス、抽象メソッドの扱いについて解説しました。

Pythonでは、abcモジュールを使うことで抽象クラス、抽象メソッドを定義することができ、抽象メソッドの実装を強制することでポリモーフィズムを実現できます。この記事では簡単な例を使ってabcモジュールの使用方法を紹介しました。

抽象クラス、抽象メソッドの考え方を理解していただき、うまく活用できるようになってもらいたいと思います。

Note

abcモジュールの公式ドキュメントはこちらを参照してください。