Pythonのクラスの継承についてはすでに学びました。
これまでは一つのクラスを継承していましたが、複数のクラスから継承することもできます。これを多重継承と言います。
ここでは複数のクラスを準備して多重継承の動きを簡単に見て行きましょう。
多重継承
クラスの多重継承の方法は、これまでのクラスの継承と同じように、クラス定義の丸括弧()の中に継承元のクラスをカンマで区切って指定します。
class クラス名(基底クラスA, 基底クラスB):
pass
この書き方では親クラスを2つ指定していますが、理屈の上ではいくつも書くことができます。ただ、それはより複雑になってしまうの現実的では無いでしょう。
では、簡単なコードで多重継承を見ていきましょう。
class Animal():
def walk(self):
print("歩きますよ。")
class Bird():
def voice(self):
print("鳴きますよ。")
class Duck(Animal, Bird):
def fly(self):
print("少しは飛びますよ。")
duck = Duck()
duck.walk()
duck.voice()
duck.fly()
Animal、Bird、Duckの3つのクラスを用意しました。Duckの丸括弧の中に二つのクラス名が入っていて多重継承になっているのがわかります。
Duck()をオブジェクト化して、継承先のクラスにそれぞれ定義しているメソッドを呼び出しています。
実行してみましょう。(ファイル名をmultiple_inheritance.pyにして、Atomで実行しています)
どのクラスのメソッドも実行できているので、多重継承の意味がわかりますね。
多重継承の順番
では、このコードを次のように変えてみましょう。
class Animal():
def walk(self):
print("歩きますよ。")
def voice(self): # Birdクラスと同じ名前の関数を定義しました。
print("吠えますよ。")
class Bird():
def voice(self):
print("鳴きますよ。")
class Duck(Animal, Bird):
def fly(self):
print("少しは飛びますよ。")
duck = Duck()
duck.walk()
duck.voice()
duck.fly()
Animalクラスの中に、Birdクラスに定義されているメソッドと同じ名前のvoice()関数を違う結果が返されるコードに書き加えました。他はそのままです。
これを実行するとどうなるでしょう?
ここでは、Animalクラスに定義したvoiceメソッドが呼び出されています。
これは多重継承には継承する順番があるからです。多重継承はクラスを書いた順番に実行され、実行されたら、他の同じ名前のメソッドは実行されません。
次のように継承の順番だけを変更してみます。
class Duck( Bird, Animal): # 継承するクラスの順番を変えてみる
def fly(self):
print("少しは飛びますよ。")
実行するとこうなります。
今度はBirdのvoiceメソッドが実行されています。
このように、多重継承には左側から読むという順番があり、同じメソッド名があれば、それより右側のクラスのメソッドは呼び出されないということを覚えておきましょう。
プログラミングを書いていく時に、最初はそれぞれのクラスだけで動かす設計のつもりであっても、次第にコードが大きくなって多重継承が必要な場合が出てくるような時に、こういう書き方をすることになります。
ただし、継承の順番を意識していないと、思った動きにならならずにエラーになることもあるので注意が必要ですので、そのあたりを念頭に置いてプログラミングするか、多重継承しないような設計を意識することも必要です。
まとめ
Pythonのクラスの継承は、複数の親クラス(基底クラス)をまとめて継承することができます。これを多重継承と言います。
多重継承は、これまでの継承の書き方と同じで、カンマで区切って複数のクラスを書き込みます。
多重継承には順番があり、左側に書いて継承したクラスから読み込まれます。ですから、多重継承したクラスにそれぞれ同じ名前のメソッドがあれば、一番左側のメソッドが実行されて、あとは無視されます。
多重継承の順番によってはエラーが起こったり、思ったような動きにならなくなるので、継承の順番をしっかり意識するか、多重継承しないようにコードを設計することも必要です。