クラス (2)継承

クラスの継承

Python ではクラスの継承に多重継承ができる。クラスを継承するには、class 文のクラス名のあとの括弧の中に継承したいクラス名を列挙すればいい。

class Foo:
    def foo(self):
        print "This is foo."

class Bar:
    def bar(self):
        print "This is bar."

class Baz(Foo, Bar):
    def baz(self):
        print "This is baz."

if __name__ == '__main__':
    baz = Baz()
    baz.foo()
    baz.bar()
    baz.baz()

BazクラスはFooクラスとBarクラスを継承していて、加えて独自のメソッドbarを持っている。
これを実行すると:

^o^ > python inheritance.py
This is foo.
This is bar.
This is baz.

FooクラスとBarクラスそれぞれのメソッドが使えることがわかる。

メソッドのオーバーライド

次に、Bazクラスでbarメソッドを書き換え(オーバーライド)てみる。

class Foo:
    def foo(self):
        print "This is foo."

class Bar:
    def bar(self):
        print "This is bar."

class Baz(Foo, Bar):
    def baz(self):
        print "This is baz."

    def bar(self):
        print "This is baz, instead bar."

if __name__ == '__main__':
    baz = Baz()
    baz.foo()
    baz.bar()
    baz.baz()

実行結果:

^o^ > python inheritance2.py
This is foo.
This is baz, instead bar.
This is baz.

barメソッドが書き換わっている。こんな風に、継承したクラス(サブクラス)で継承もとのクラス(スーパークラス)のメソッドをオーバーライドすることができる。

メソッド名の衝突と継承の順番

ところで、多重継承するとメソッド名が衝突することが考えられる。つまり2つのスーパークラスそれぞれに同じ名前のメソッドが定義されていた場合だ。ちょっと試してみよう。

class Foo:
    def hello(self):
        print "Hello, this is Foo."

class Bar:
    def hello(self):
        print "Hello, this is Bar."

class Baz(Foo, Bar):
    pass

if __name__ == '__main__':
    baz = Baz()
    baz.hello()

二つのスーパークラスFooとBarには同じ名前のhelloメソッドがあって、サブクラスBazから呼び出している。実行すると:

^o^ > python inheritance3.py
Hello, this is Foo.

Fooクラスのメソッドが実行された。これはクラスを継承するときにFooを先に書いたせい、なのか?ためしにFooとBarを逆にしてみよう。

class Foo:
    def hello(self):
        print "Hello, this is Foo."

class Bar:
    def hello(self):
        print "Hello, this is Bar."

class Baz(Bar, Foo):
    pass

if __name__ == '__main__':
    baz = Baz()
    baz.hello()

さっきと変わっているのは11行目だけだ。スーパークラスの指定にBarを先に書いている。これを実行すると:

^o^ > python inheritance3a.py
Hello, this is Bar.

今度はBarクラスのメソッドが実行された。スーパークラスでメソッド名が衝突している場合、サブクラスでどちらが呼び出されるのかは、継承するときに列挙した順番によるみたいだ。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください