ペンギンは鳥だけど飛べない
「ペンギンは鳥だけど飛べない。」オブジェクト指向の継承を説明するときに使われる例です。ペンギンクラスは鳥クラスを継承したいんだけど、ペンギンは普通の鳥と違って飛べないというジレンマがあります。
Rubyならではの実装例を2つほど考えてみました。
実装例(1) ペンギンクラスでflyメソッドを呼び出せないようにする場合。
class Bird def fly # 普通の鳥は飛べる。 puts 'pata pata...' end end class Owl < Bird # ふくろうクラスは鳥クラスを継承する。 end class Penguin < Bird # ペンギンクラスは鳥クラスを継承する。 undef :fly # でもペンギンは飛べない。 # メソッドが呼び出されるのを禁止する。 end Owl.new.fly # => pata pata... ふくろうは飛べる。 Penguin.new.fly # => NoMethodError ペンギンは飛べない。
実装例(2) 飛行能力(flyメソッド)を切り出してふくろうクラスにmix-inする場合(ある意味多重継承)。
module FlyingAbility # 飛行能力(flyメソッド)を切り出す。 def fly puts 'pata pata...' end end class Bird end class Owl < Bird # ふくろうクラスは鳥クラスを継承する。 include FlyingAbility # ふくろうには飛行能力を与える。 end class Penguin < Bird # ペンギンクラスは鳥クラスを継承する。 # ペンギンには飛行能力を与えない。 end Owl.new.fly # => pata pata... ふくろうは飛べる。 Penguin.new.fly # => NoMethodError ペンギンは飛べない。
Rubyは動的な言語なのでいろいろできますね。ちなみにflyメソッドに反応できるかどうかは、respond_to?(:fly)で調べることができます。
これまた思考停止しそうですが…