Pythonでのポリモーフィズムと抽象クラス、抽象メソッドの扱いについて解説します。
ポリモーフィズム(polymorphism)
クラス実装において、異なるクラスが共通のインターフェース(メソッドやプロパティ)を実装し、同じメソッド名で異なる振る舞いをすることをポリモーフィズム(多様性・多相性)と言います。
例として、Personクラスを継承したTeacherクラスとDoctorクラスを考えてみます。
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
モジュールの使用方法を紹介しました。
抽象クラス、抽象メソッドの考え方を理解していただき、うまく活用できるようになってもらいたいと思います。
abc
モジュールの公式ドキュメントはこちらを参照してください。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。