継承はメソッドを使いまわすためにあるのでない

まだまだオブジェクト指向を極めたわけではないのですが、最近気になったこと。

オブジェクト指向の継承はメソッドを使いまわすためにあるのではないということです。

Fooというクラスがあって、BarというクラスがFooを継承(inherit)しているとする。つまり、Bar is a Fooとなっている。

このとき、Barに求められるのは、Fooと同じメソッドを持つということだけではない。メソッドの動作は変えても良いが、意味は変えてはならない。プログラム内でFooクラスを使っているところをBarに置き換えても、Fooを使っているつもりで動作しなければならない。

これを守ろうと思ったら、継承はむやみにできなくなると思うです。

ただメソッドを使いまわしたいだけなら継承ではなくて、委譲(delegate)をするべきなのです。例えば、Fooを継承したBarというクラスがあったとして、他にFooを継承したクラスBazが欲しい時にBarのメソッドを使いまわしたいとしよう。このとき、BarBazに置き換えることができないなら、BazBarを継承してはいけない。Bazは内部変数としてBarを持って、適宜Barのメソッドを呼び出すべき。

○○原則という名前がついていそうなものですが、私は知りません。当たり前すぎてついていないのかな?しかし、浸透していないように思う。


2016-04-10

関連する気付きについて書きました。

リスコフの置換原則は呼び出し側にも責任が伴う - 超ウィザード級ハッカーのたのしみ