今回の解説は継承から始まり、オブジェクト指向の基礎まで踏み込みます。
クラスを継承やインスタンス化するだけでは、オブジェクト指向の旨味を存分に味わえません。
また他人が作った、あるいはフレームワークに備わっているクラスを使うことは多々ありますので、継承やオブジェクト指向はとても大事です。
それでは解説を始めましょう。
継承をソースベースで解説
継承とは何かというのは、前記事「【Ruby入門】クラスの継承、オーバーライド」で解説しました。
ここではRubyでどう実装するかというのをやってみましょう。具体例として、今までの解説で出てきたBookクラスを使います。
Bookクラスは以下のとおりです。在庫に関連するものを追加し、説明に関係ないものを消しました。
またBookクラスを親クラスとして、言語(つまり本は何語で書かれているのか)まで管理する子クラスBookLangクラスを定義しました。
インスタンス化までを以下にまとめたので、そのままコピペして実行できます。
class Book # アクセサメソッド attr_accessor :title attr_accessor :author def initialize(mytitle = "", myauthor = "") @title = mytitle @author = myauthor @stock = stock() end # 在庫を計算する def stock # 普通に計算するだけ # 常に変動するので、呼ばれた都度計算 @stock = 3 # とりあえず適当に3とする end end class BookLang < Book attr_accessor :lang def initialize(mytitle,myauthor,lang) super mytitle, myauthor @lang = lang end end bl = BookLang.new("タイトル", "著者", "日本語") p bl.title p bl.author p bl.lang
[実行結果]
"タイトル" "著者" "日本語"
引数で渡したものが表示されただけですが、なんとか動きました!!
Bookクラスを基本として、言語のあつかいだけを追加できました。
ここで注目して欲しいのは、親クラスに子クラスの要素は一切ないということです。
子クラスに親クラスでもつインスタンス変数へのアクセサを記述する必要がないことも注目してください。
親クラスに手を加えることなく子クラスだけで拡張できるというすごさを実感できましたか?
ただし、解説をしていない箇所がたくさんあります。以降、その解説をします。
インスタンス化
今まで解説したとおり、クラスを実体化する行為です。
基本書式は以下です。
参照用変数 = クラス.new(引数)
先ほどのソースでは以下を書きました。
bl = BookLang.new("タイトル", "著者", "日本語")
以降参照用変数を経由して、あたかもインスタンスをさわっているかのようにあつかえます。
もちろん、親クラス単体でもインスタンス化できます。
book = Book.new("タイトル", "著者")
オーバーライド
Bookクラスでは、「図書館における本館の閲覧場所だけの在庫数を計算する」と仮定しました。
ある日、新たに別館の在庫数も合わせた合計で計算する必要が出てきたとしましょう。
Bookクラスにあまり手を入れたくないし、さあどうしましょうか。
そこで継承をうまく使ってやってみましょう。
本館と別館の総数を計算するBookAmountというクラスを定義します。
Bookクラスはそのままで結構です。
class BookAmount < Book def initialize(mytitle,myauthor) super end # 在庫を計算する(本館+別館の総数) def stock # 本館と別館の総数を計算するロジック @stock = 4 # とりあえず適当に4とする end end ba = BookAmount.new("タイトル", "著者") p ba.title p ba.author p ba.stock
[実行結果]
"タイトル" "著者" 4
結果の4に注目です。
stockというメソッドをサブクラスBookAmoutで上書きしました。
その結果、stockという変数に4という値が入りました。
上書き(つまりオーバーライド)されて4になったこと、おわかりいただけたでしょうか?
※ここではオーバーライドの解説をメインとしているので、本館と別館をどうやって合計するのか?というロジックは考えていません。
ポリモフィズム
ポリモフィズムとは、オブジェクト指向的には問題ある解説かもしれませんが、要は「呼ぶ側は呼ばれる側のことは一切考える必要がなく、同じ呼び方でよい」というものです。
先ほどの別館もカウントするバージョンに加えて「在庫が閲覧場所と奥の倉庫に分散している」バージョンを作ってみましょう。
class BookFrontandBack < Book def initialize(mytitle,myauthor) super end # 在庫を計算する(閲覧場所と奥の倉庫の総数) def stock # 閲覧場所と奥の倉庫の総数 @stock = 5 # とりあえず適当に5とする end end
これで基本のBook、別館との総計のBookAmount、閲覧場所と奥の倉庫の総数のBookFrontandBackが出揃いました。
呼び出しましょう。
まずは基本クラスです。
book = Book.new p book.count
次に、別館との総計バージョンです。
book = BooAmount.new p book.count
さらに、閲覧場所と奥の倉庫の総計バージョンです。
book = BookFrontandBack.new p book.count
お気づきでしょうか?
「p book.count」はまったく同じです!
これがポリモフィズムです。
仮に呼び出し先がまだできていないとしても、この呼び出し方は同じなので先に作ることができます。
便利ですよね。
まとめ
これでクラスやオブジェクトの基本解説は終わりです。
お疲れさまでした!
本来は奥深い概念ですが、あまりに深く解説すると余計に分かりづらくなるので、難解なことなるべくさけて解説しました。
最低限のプログラミングはこれで大丈夫かと思います。
もちろん興味を持たれた方は、どんどん深掘りしてみてくださいね!