CodeGym /Javaコース /Python SELF JA /階層の初期化

階層の初期化

Python SELF JA
レベル 16 , レッスン 1
使用可能

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つあるんだ:動物のタイプとその名前。継承クラスのコンストラクタでは名前だけを受け取っている。

クラスDogCatのコンストラクタ内で、基底クラスのコンストラクタに何を渡すかが決まるんだよ。それで動物のタイプ名「犬」と「猫」を渡してるんだ。

だから:

  • 基底クラスのコンストラクタは、必ず継承クラスのコンストラクタで呼び出す必要があるんだ。
  • それには 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))  # 出力: 引き出し限度を超えました
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION