6章
クラスによる継承
サブクラスでメッセージに応答できない→スーパークラス(上位のクラス)にメッセージを委譲する。
継承を使うべき場所
既にBicycleクラスがある。
|
|
もしロードバイクを追加したいときは?
ロードバイクは固有のfront_shock
とrear_shock
を必要とする。
そして、spareに必要なものも違う。
|
|
新たなstyle
が増えるたびにif文がひたすら増える。
さらに、front_shock
とrear_shock
はstyleが:road
のときには値が入らないんだよね。ということは、この値を使うときには毎回if分岐する必要がある……。
自身の分類を保持する属性を確認して、メッセージを確定するというif文には注意!!
埋め込まれた型を見つける
- type
- category
- style
これらを変数で管理しているときは要注意。だって、それって意味としてはclass
じゃん?
とはいえ、Bicycle
とMountainBike
を単独の別のクラスにするには、同じものがありすぎる……DRYじゃない。
そんなときは継承です!
継承は、共通の振る舞いを持つものの、いくつかの面においては異なるという、強く関連した型の問題を解決します。
継承について
オブジェクトによる受け取ったメッセージの処理方法
- 直接応答する(自分の責任なので自分が対応する)
- 他のオブジェクトにメッセージを渡して応答してもらう(自分から責任を外す=委譲)
継承は、この後者の関係を自動的に定義する。
自分がメッセージを理解できなかったら、継承元に「このメッセージの応答よろしくお願いしまーす」を渡す。
単一継承
単一継承:親を絶対に一つしか持たない
もし単一継承じゃなかったら?
……理解できないメッセージをどっちの親に渡せばいいの?
……親1と親2に同じメソッドが定義されていたらどっちが優先される?
なので、優先順位を明確にするために、多くのオブジェクト指向言語は単一継承を採用している。
ちなみに……Rubyでは、「ただのクラス」のスーパークラスはObject
クラスになる。
|
|
ちなみに
nil
はNilClass
のインスタンスであり、(他のオブジェクトがそうであるように)Object
を継承している。
nil?
メソッドはNilClass
内ではtrue
を返すように定義され、Object
内ではfalse
を返すように定義されている。
nil以外のクラスのインスタンスの場合は、継承を遡っていき、true
を返す。
|
|
そっと私は見なかったことにした。Kernel
はCらへんなので……。
テンプレートメソッド
superクラスで定義したメソッドがサブクラスでしか定義されていないってなんか嫌じゃね?
サブクラスを新たに作ったときに、そのクラスを絶対使わないといけないけど、それに気づけない。
NoMethodErrorじゃなくってあえて名前をつけたエラーをraiseすることで原因がわかりやすくなる!
エラーが出るのは同じじゃね?って思うけど、それが奥深くに入ってしまうとスタックを追うのが超面倒。
こういうときにエラーが出るよなあってのが実装時にわかっているなら、未来のためにもちゃんとそれ用にエラーがraiseするようにしておこうね……。
テンプレートメソッド(Template Method) | Ruby デザインパターン | 酒と涙とRubyとRailsと
テンプレートメソッド自体は継承じゃなくても「良い」。
最終的に手順を示す形のメソッド。メソッドだけを入れたメソッド。
省略
最終的な形
|
|