Fire Engineering

化学の研究者→消防士→ITエンジニア(2016年11月〜)

第3回 クラスの継承と拡張 〜Rubyの勉強〜

 Rubyを正しく理解するために書いている「〜Rubyの勉強〜」

  第1回 オブジェクト指向とは

  第2回 クラスとインスタンス

に引き続き、第3回はクラスの継承と拡張についてです。

継承、拡張とは?

 第2回で、クラスはオブジェクトの特徴をまとめた設計図のようなものであることがわかりました。何かを新しいものを設計することを考えると、わざわざ毎回ゼロから設計図を作るのって大変ですよね。建物にしろ、車にしろ、新しいものを作る際は、既存の設計図を参考にし、それを修正したり、何か追加したりするはずです。クラスにおいて、すでに定義されているクラスの機能を受け継ぎ、新たなクラスを作成することを「クラスを継承する」と言います。既存のクラスを継承して新たにクラスを作成する場合は以下のように記述します。

(継承によって新しく作られたクラスをサブクラス、継承のもとになったクラスをスーパークラスと言います。)

class サブクラス名 < スーパークラス名
 #クラスの定義
end

 継承したクラスではスーパークラス内で定義されているメソッドが利用できます。さらに、既存の機能に加えて、新しい機能を追加することができ、これが「クラスを拡張する」ということです。

 これらの機能がなぜ有効であるかということについて例をあげて考えていきたいと思います。例として、画面に時間を表示する時計機能を作ることを考えます。この時計では、ユーザーが好みに応じてデジタル表示とアナログ表示に切り替えられる機能をもたせるとします。その場合、クラスの設計としてはどうすればよいでしょうか?「アナログ時計クラス」と「デジタル時計クラス」を作ることになると思いますが、両者は、現在時刻を取得する方法やアラーム機能などの共通の機能を有しています。ここで、「アナログ時計クラス」と「デジタル時計クラス」をそれぞれ独立して作成すると、共通の機能の部分が重複しており、DRY(Don’t Repeat Yourself、Ruby on Railsの設計哲学の一つ)に反することになります。したがって、「時計クラス」という基本機能をもったクラスを作成し、「アナ ログ時計クラス」と「デジタル時計クラス」が「時計クラス」を継承して、それぞれ固有の機能を追加する、といったようにした方がよいでしょう。このように、継承は同じような機能を持った複数のクラスを作る場合に非常に便利なメカニズムです。

Rubyにおけるクラスの継承

 Rubyでは、すべてのクラスはBasicObjectクラスのサブクラスとなっています。BasicObjectクラスにはRubyの世界のオブジェクトとして必要最低限の機能が定義されています。さらにその下にObjectクラスが存在し、ここにもオブジェクトに共通の機能が定義されています。下記にRubyの組み込みクラスの継承関係の図を載せておきます。

f:id:hirotsuru314:20160417211701j:plain

文字列や配列などはObjectクラスのサブクラスであることがわかります。また、クラス作成の際に、特にスーパークラスを指定しない場合は、Objectクラスがスーパークラスとなります。

単一継承について

 Rubyは単一継承というものをサポートしています。単一継承では、あるクラスを定義するときに、スーパークラス1つのみを継承することができます。つまり下の図のように、あるスーパークラスから複数のサブクラスを作成することはできますが、あるサブクラスが複数スーパークラスを継承することはできません。

f:id:hirotsuru314:20160417212038j:plain

 図で×を示したものは、多重継承と呼ばれます。単一継承は、継承関係が単純で理解しやすい木構造(ツリー構造)になるのが特徴です。類似部分を共通化して差異部分のみ別々のクラスに分けることで、スーパークラス(親)をたどっていくとと汎化され、サブクラス(子)に向かうと特化になります。

 Ruby は、基本的には単一継承ですが、Mix-in という機能を導入することで、多重継承への対応を行っています。これにより、単一継承のシンプルさを保ちつつ多重継承の良いところを取り込めるようにしてあります。 Mix-in については次回説明します。

 以上が、クラスの継承と拡張についての説明ですが、ちょっと説明が抽象的でしたね。。これはクラスの概念の本当に触りだけですが、なんとなくオブジェクト指向の特徴とメリットがつかめてきたんじゃないかと思っています。次回は、「モジュールとMix-in」です!モジュールってクラスと似た機能を持っていてよくわからない。そんな疑問を解消できるようにしたいと思います。また、よろしくお願いします!