6.6 superによる親への支援要請
子クラスが親クラスのメソッドをオーバーライド(上書き)すると、親クラスの元のメソッドは自動的には呼び出されなくなります。しかし、子クラス独自の処理をしつつ、親クラスの元の機能も利用したい場合があります。
そのようなときに活躍するのが super() 関数です。
super() を使った親メソッドの呼び出し
Section titled “super() を使った親メソッドの呼び出し”例として、名前(name)を持つ親クラス Person と、それに加えて電子メールアドレス(email)を持つ子クラス EmailPerson を定義してみましょう。
# 親クラスclass Person(): def __init__(self, name): self.name = name
# 子クラスclass EmailPerson(Person): # email引数を追加した独自の __init__ def __init__(self, name, email): # 1. 親クラス(Person)の __init__ を呼び出して name の設定を任せる super().__init__(name)
# 2. 子クラス(EmailPerson)独自の email の設定を行う self.email = emailこの子クラスの __init__() 内では、以下のような処理が行われています。
super()が親クラスであるPersonの定義を取り出します。super().__init__(name)によって親の初期化メソッドが呼び出されます。このとき、self引数(オブジェクト自身)の受け渡しはPythonが自動で処理してくれるため、プログラマーは必要な引数(ここではname)だけを渡せば済みます。- 最後に
self.email = emailで、EmailPerson独自の属性を保存します。
オブジェクトの作成と確認
Section titled “オブジェクトの作成と確認”実際に EmailPerson クラスからオブジェクトを作って、両方の属性にアクセスできるか確認してみます。
bob = EmailPerson('Bob Frapples', 'bob@frapples.com')
# 親クラスの __init__ で設定された属性print(bob.name)# 出力: Bob Frapples
# 子クラスの __init__ で設定された属性print(bob.email)# 出力: bob@frapples.comなぜ super() を使うべきなのか?
Section titled “なぜ super() を使うべきなのか?”EmailPerson クラスの __init__ の中で、super() を使わずに直接 self.name = name と書くことも可能です。
しかし、あえて super() を使って親に仕事を任せることには大きなメリットがあります。
それは、将来もし親クラス (Person) の定義が変更されたとしても、super() を使っていればその変更が自動的に子クラス (EmailPerson) にも反映されるという点です。
継承の利点を最大限に活かすために、子クラスが親クラスの助けを必要とする場合は super() を使うようにしましょう。