多重継承

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

10.1 複数クラスからの継承

多重継承はPythonでクラスが複数の親クラスから 属性やメソッドを継承することを可能にするんだ。これにより コードの再利用がしやすくなるけど、複雑な階層や潜在的な コンフリクトにつながることもあるよ。

自分のクラスに親を5つも指定できるってのは、すごく可能性を広げてコードを書くのを便利にしてくれるんだ。やり方はとてもシンプルで、親クラスをカンマで区切ってリストすればいいだけ:


class Base1:
    def method1(self):
        print("Method1 from Base1")
        
class Base2:
    def method2(self):
        print("Method2 from Base2")
        
class Derived(Base1, Base2):
    pass
        
obj = Derived()
obj.method1()
obj.method2()     
        

予定通りに動いてるね — いい感じだ。

でも、多重継承には注意が必要な複雑な部分もあるんだ。どうやってそれが動くのか、そしてそれに関連する問題をどう避けるかを見てみよう。

10.2 いくつかの基本クラスに同じメソッドがある場合の呼び出し

クラスはカッコ内にリストされた複数の親クラスから属性やメソッドを継承できる。そして、それらの属性やメソッドが同じ名前を持つこともある:


class Base1:
    def method(self):
        print("Method from Base1")
        
class Base2:
    def method(self):
        print("Method from Base2")
        
class Derived(Base1, Base2):
    pass
        

obj = Derived()
obj.method() # どのメソッドが呼ばれるかな?
        

この例では、DerivedクラスはBase1Base2から継承されている。method()を呼び出すとき、Pythonは最初にリストされたクラスのメソッド、つまりBase1のメソッドを選ぶんだ。

でもそれってちょっと直感的じゃないよね?もし誰かが基底クラスのコードを変更したら、アプリ全体のロジックに影響が出るかもしれないし、何が問題かすぐに分からなかったりするんだ。ちょっと違うメソッドが呼ばれたりするだけ:)

10.3 多重継承でのsuper()の使い方

もう1つ興味深いことは、super()を使って多重継承のときに基底クラスのメソッドを呼び出すことだ。

例を見てみよう:


class Base1:
    def method(self):
        print("Method from Base1")
        super().method()
        
class Base2:
    def method(self):
        print("Method from Base2")
        super().method()
        
class Derived(Base1, Base2):
    def method(self):
        print("Method from Derived")
        super().method()
         

obj = Derived()
obj.method()
        

さて、出力はどうなるだろう?

Method from Derived
Method from Base1

それとも

Method from Derived
Method from Base2 

実はね、出力はこうなるんだよ:

Method from Derived
Method from Base1
Method from Base2

super().method()のコードは、各基底クラスのmethod()を呼び出してしまうんだ!まさに最初に多重継承について話したときに言ってた誰もが迷いやすいところなんだよね。

10.4 菱形の(Diamond) 継承

最後に、古典的な問題であるダイヤモンド継承。実例で説明する方がわかりやすいかな:

コードで表すとこんな感じになるかも:


class A:
    def method(self):
        print("Method from A")
        
class B(A):
    def method(self):
        print("Method from B")
        super().method()
        
class C(A):
    def method(self):
        print("Method from C")
        super().method()
        
class D(B, C):
    def method(self):
        print("Method from D")
        super().method()
         
         
        
obj = D()
obj.method()
        

出力はこうなるだろう:

Method from D
Method from B
Method from C
Method from A 

多重継承で少しでも方向性をつかむには、Pythonが親クラスのフィールドやメソッドをどの順序で探すのかをしっかり理解する必要があるんだ。このことを次の講義で学べるよ。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION