プログラミングを行う上で、可視性が高く、理解しやすいことは、重要な要素の一つかと思います。
これにより、結果的に障害を組み込んでしまう機会も軽減できるかもしれません。
それを可能にする方法の1つとして考えられるのが「オブジェクト指向(詳細は、こちら)」です。
今回は、そんなオブジェクト指向をpythonで実装する方法のうち、「クラスの継承」に関する内容について、まとめます。
「クラスの実装と利用」については、こちらを参照ください。
基礎知識
本記事で使用する重要な用語を簡単にまとめておきます。詳細を知りたい場合は、こちらを参考にしてください。
継承
既存のクラスの処理を引き継ぎ、再利用を可能にする仕組みのことです。
既存のクラスをベースとした「別の新しいクラス」を作成することができます。
この時、引き継ぎ元を「スーパークラス」、引き継ぎ先を「サブクラス」と呼びます。
ポリモーフィズム
同じメソッド名で、異なる処理を行う仕組みのことです。
オーバーライド
ポリモーフィズムを実装する方法の1つです。
スーパークラスで存在しているメソッドの内容を上書きして、別のメソッドにすることができます。
オーバーロード
ポリモーフィズムを実装する方法の1つです。
スーパークラスに存在している元々のメソッドを残しつつ、同名のメソッドを複数定義することができます。
継承の実装と利用
実装するには、クラスの宣言時に、親となるスーパークラスを指定してあげる必要があります。
宣言の基本形は、「class サブクラス名(スーパークラス名):」です。
これにより、スーパークラスで定義されているフィールドの値、メソッドの内容が引き継がれるようになります。
コードサンプル:
class Super_Class:
super_class_name = ‘スーパークラス’
def show_super(self):
print(f'{self.super_class_name}のメソッドです。’)
class Sub_Class(Super_Class):
sub_class_name = ‘サブクラス’
def show_sub(self):
print(f'{self.sub_class_name}のメソッドです。’)
def show_super_from_sub(self):
print(f'{self.sub_class_name}から呼び出した{self.super_class_name}のメソッドです。’)
sc = Sub_Class()
sc.show_super()
sc.show_sub()
sc.show_super_from_sub()
実行結果:
スーパークラスのメソッドです。
サブクラスのメソッドです。
サブクラスから呼び出したスーパークラスのメソッドです。
上記のコードサンプルでは、サブクラスのオブジェクト「sc」から、スーパークラスクラスのメソッドを「sc.show_super()」で使用しています。
また、「sc.show_sub()」や「sc.show_super_from_sub()」で、サブクラスにて新規で定義したメソッドも利用できています。
「sc.show_super_from_sub()」では、スーパークラスの変数を使用できていることも分かります。
オーバーライドの実装と利用
実装するには、スーパークラスで宣言したメソッドをそのまま利用します。
「メソッド名」はもちろんのこと、「引数」「型」などは変更してはいけません。
あくまで、メソッドで行う処理を書き換えることになります。
コードサンプル:
class Super_Class:
super_class_name = ‘スーパークラス’
def show(self):
pr int(f'{self.super_class_name}のメソッドです。’)
class Sub_Class(Super_Class):
sub_class_name = ‘サブクラス’
def show(self):
print(f'{self.sub_class_name}のメソッドです。’)
sc = Sub_Class()
sc.show()
実行結果:
サブクラスのメソッドです。
上記のコードサンプルでは、スーパークラスで定義した「show(self)」のメソッドをサブクラスで上書きしています。
オーバーロードの実装と利用
オーバーロードを実装するための条件としては、メソッド名以外の要素で差別化を行うのが条件となっています。
宣言した時の「引数の数」「引数の型」を変更することで実現が可能になります。
しかし、Pythonにおいては、この方法でメソッドのオーバーロードはできません。
その理由として、Pythonでは「型の概念がない」「同名メソッドが定義されている場合は、後勝ちとなる」ということに起因します。
そのため、以下のようなコードを記載した場合は、TypeErrorになってしまいます。
コードサンプル:
class Super_Class:
super_class_name = ‘スーパークラス’
def show(self):
print(f'{self.super_class_name}のメソッドです。’)
class Sub_Class(Super_Class):
sub_class_name = ‘サブクラスのインスタンス変数’
def show(self):
print(f'{self.sub_class_name}のメソッドです。’)
def show(self, sub_class_name):
print(f'{sub_class_name}から呼び出した{self.super_class_name}のメソッドです。’)
sc = Sub_Class()
sc.show()
sc.show(‘サブクラス’)
実行結果:
TypeError: Sub_Class.show() missing 1 required positional argument: ‘sub_class_name’
これは、「sc.show()」で呼び出すメソッドが、スーパークラスで定義した引数なしのshowメソッドでも、サブクラスで定義した引数なしのshowメソッドでもないことを意味しています。
「def show(self, sub_class_name):」のメソッドが採用されたために、引数がないとエラーが出ているのです。
ただし、デコレータを使用するなどの「functools」モジュールに含まれる「singledispatch」デコレータを使用することで、オーバーロードのような実装を行うことは可能なようです。
まとめ
今回は、pythonにおけるクラスの継承に関する内容についてまとめてみました。
大規模なソースコードになるほど重要な内容になってくると思います。
ぜひ、参考にしてみて下さい。