7.1 メソッド super()
継承の階層に触れたので、基底クラスのフィールドとメソッドの扱いについて話すといいかな。Pythonでは特別な
メソッド super()
があるんだ。これは子クラス内で基底クラスのメソッドを呼び出すときに使うよ。
使いどころは主に3つあるよ:
親クラスのメソッドを呼び出す:
super()
メソッドを使うと、親クラスのメソッドを子クラスから呼び出せるんだ。親クラスの名前を直接指定しなくていいんだよ。特に多重継承を使うときに役立って、クラス階層を変更したときのエラーを避けられるんだ。
基底クラスの初期化:
super()
はよく子クラスのコンストラクタで使われて、基底クラスのコンストラクタを呼び出すんだ。それで子クラスで基底クラスの属性を初期化できるんだよ。
多重継承のサポート:
多重継承の場合、
super()
はメソッドの呼び出し順序(MRO, Method Resolution Order)を正しく解決してくれるから、親クラスのメソッドを直接呼び出すよりも優れているんだ。このことについてはもう少し後で話そう。
7.2 基底クラスのコンストラクタ
基底クラスのコンストラクタは明示的に呼び出さなきゃいけないんだ。自動的にやってくれるように見えるけど、実際にはそうじゃないんだよ。基底クラスのコンストラクタはいつも明示的に呼び出す必要があるんだ。特別な引数を渡す場合が多いからね。
例:
class Animal:
def __init__(self, type, name):
self.type = type
self.name = name
class Dog(Animal):
def __init__(self, name):
super().__init__("犬", name) # 基底クラスのコンストラクタを呼び出す
class Cat(Animal):
def __init__(self, name):
super().__init__("猫", name) # 基底クラスのコンストラクタを呼び出す
# Dog オブジェクトを作成する
dog = Dog("Buddy")
print(dog)
この例では、基底クラス(Animal)
のコンストラクタにはパラメータが2つあるんだ:動物のタイプとその名前。継承クラスのコンストラクタでは名前だけを受け取っている。
クラスDog
とCat
のコンストラクタ内で、基底クラスのコンストラクタに何を渡すかが決まるんだよ。それで動物のタイプ名「犬」と「猫」を渡してるんだ。
だから:
- 基底クラスのコンストラクタは、必ず継承クラスのコンストラクタで呼び出す必要があるんだ。
- それには
super()
メソッドを使うんだ。 -
引数
self
を別々に渡す必要はないよ — Python がメソッド呼び出しのときに自動的にそれを提供してくれるんだ。
7.3 super()
メソッドの利用
super()
メソッド は Python でコンストラクタだけでなく、クラスの他のメソッドでも親クラスのメソッドを呼び出すのに使えるんだ。それは親クラスで定義されたメソッドの動作を拡張したり修正する必要があるときに便利なんだよ。
いくつかの例を見てみよう:
子メソッドで親クラスのメソッドを呼び出す
この例では、Dog
クラスのspeak()
メソッドはまず super()
を使ってAnimal
クラスの speak()
メソッドを呼び出し、その後に独自の動作を追加してるんだ。
class Animal:
def speak(self):
return "何かの動物の音"
class Dog(Animal):
def speak(self):
parent_speech = super().speak() # 親クラスのメソッドを呼び出す
return f"{parent_speech} そして犬が吠えるよ!"
dog = Dog()
print(dog.speak()) # 出力される: 何かの動物の音 そして犬が吠えるよ!
状態を確認するために親クラスのメソッドを呼び出す
この例では、Dog
クラスのcheck_health()
メソッドが Animal
クラスの
check_health()
メソッドを呼び出して、追加のチェックを行っているんだ。
class Animal:
def check_health(self):
return "動物は健康です"
class Dog(Animal):
def check_health(self):
parent_check = super().check_health() # 親クラスのメソッドを呼び出す
return f"{parent_check}. 犬は散歩が必要です!"
dog = Dog()
print(dog.check_health()) # 出力: 動物は健康です. 犬は散歩が必要です!
状態を変更するメソッドで親クラスのメソッドを呼び出す
この例では、SavingsAccount
クラスのwithdraw()
メソッドが最初に引き出し制限を超えていないか確認して、問題がなければBankAccount
クラスのwithdraw()
メソッドを呼び出して処理を行うんだ。
class BankAccount:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
return f"{amount}を引き出しました。新しいバランス: {self.balance}"
return "資金不足"
class SavingsAccount(BankAccount):
def withdraw(self, amount):
if amount > 1000:
return "引き出し限度を超えました"
return super().withdraw(amount) # 親クラスのメソッドを呼び出す
savings = SavingsAccount(1500)
print(savings.withdraw(500)) # 出力: 500を引き出しました。新しいバランス: 1000
print(savings.withdraw(1500)) # 出力: 引き出し限度を超えました
GO TO FULL VERSION