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

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 モジュールの使用方法を紹介しました。
抽象クラス、抽象メソッドの考え方を理解していただき、うまく活用できるようになってもらいたいと思います。
上記で紹介しているソースコードについては GitHub にて公開しています。参考にしていただければと思います。



の基本.jpg)

の使い方.jpg)
