前置き
オブジェクト指向、難しいですよね。
どれだけ書いても理解できる気がしません。なのでこの記事はあくまでも私の理解です。
読んで理解の足しになればうれしいですが、混迷の度合いを深める結果になったら申し訳ありません。
オブジェクト指向とはなにか、ざっくり
良く言われるのは、オブジェクト指向とは、現実世界をそのままプログラミングするものであると言う理論ですが、これは間違っています。
ものすごく単純化して言えば、オブジェクト指向とはフレームワークです。
つまり、本来複雑な作業であるプログラミングを、一定の約束事に従うことで抽象化し、より簡単に行うための存在がオブジェクト指向ですね。
歴史的には、1972年にアラン・ケイがSmalltalkと言う言語を作るときに提唱して以来40年以上使われている事になるこのフレームワーク、当然当初から比べてもかなり拡張されていて、もはや機能を一目で俯瞰すると言うことは不可能に近いです。このあたりも難しいと言われるゆえんではないでしょうか。
オブジェクト指向という「フレームワーク」が実現したいこと
提唱者であるアラン・ケイの言葉によれば、「本質はメッセージングであり、オブジェクト指向という名付けは失敗」なのだそうです。
つまり、オブジェクト指向の実現したいことにとってオブジェクトは本質ではないと言うことになります。
現時点で私は
- 内部状態の隠蔽
- 内部実装の隠蔽
- インターフェースの厳密な定義
を機能としてもつ拡張された型を対象とするメッセージ送受信によるプログラミング
こそが、オブジェクト指向が実現したいことと捕らえています。
つまり、いわゆるオブジェクト指向三大要素、「カプセル化、継承、ポリモーフィズム」のうち、機能として存在すべきものはカプセル化だけで、ポリモーフィズム(のうち、アドホック多相)は自明なものとして導き出され、継承に至っては存在しなくても良いものとなるわけです。
アドホック多相はなぜオブジェクト指向で自明なのか
まずアドホック多相とは、同じ名前の関数を異なる引数に適用可能であり、引数によって振る舞いが変わると言う動作を指しますが、foo.bar(baz)
と記述された場合、bar(baz)というメッセージを処理する主体は必ずfooであり、動作としては(おそらく)引数一つを取るbarメソッドが呼び出されます。そして例えば、hogeクラスが引数1つを受け取るbarメソッドをもっていたとしても、fooクラスのbarメソッドが何らの影響を受けることはなく、完全に独立した動作をします。これはオブジェクト指向に沿って実装されているのであれば確実にこのように動作となります。
ちなみにですが、実装されていないメソッドに対応するメッセージが送りつけられた場合の動作は不定です。
Rubyであればmethod_missingが呼び出されるでしょうし、Javaであればビルドが通らないでしょう。
オブジェクト指向はなぜ現実世界の実装ではないか
これは単純です。
現実世界のオブジェクトはプログラムには不必要なほど複雑だからです。
例えば「可愛いわんちゃん」をプログラムしたいとき、現実世界の「犬」がもっている能力のうち、「気に入らないことがあるとうなる、噛みつく」などというものは必要ないはずですが、もし現実をそのままプログラムするとしたらこれも実装の必要がでてきます。
しかし、それに時間を割くよりは「投げたフリスビーを一生懸命取ってくる」姿や、「自分のしっぽを追いかけてぐるぐる回る」ちょっとマヌケな所をプログラムにしたいでしょう。作りたいのは可愛いわんちゃんですから。
プログラムの世界は現実よりもかなりプログラマに都合よく出来ています。具体的なものから必要な機能だけを取り出して、さらにその「もの」の外側からは内部の複雑な部分を隠し、きれいに見せるという方法がとれます。
例えば、対戦アクションゲームを作りたいとします。
1体1で、キャラクタが2人います。
勝敗を決定するためにはどちらかが死んだことが判定できないといけません。
現実世界の人に「あなた生きてますか?」と聞いた場合、どういう返事が返ってくるかはわかりません。
「見ればわかるだろ」と言われたり、生きている人に「死んでるよ」と返されるかもしれません。
逆に、返事がないからと言って死んでいるとは限らないわけです。寝ているかもしれませんし、息はあるけど死にそうでしゃべれない状況かも知れません。
が、プログラムの中の人はいついかなるときも「あなた生きてますか?」と聞かれれば正しく「はい」か「いいえ」を返してくれます。
また、現実で1対1では審判がいないので、負けを認めない人が出てくるかもしれません。
プログラムの世界では、誤審しない見えない審判を置いておいてもいいわけです。
現実は複雑であり、プログラムにすることは非常に困難です。
オブジェクト指向とはあくまでも、複雑なプログラミングを簡単にするためのフレームワークです。
現実のことはいったん忘れて、プログラミングの世界を楽しみましょう。
オブジェクト指向の理解のために
GoFと言われている凄腕のプログラマたちが、オブジェクト指向あるある集に名前をつけて、「デザインパターン」として発表しています。
詳細についてはここでは触れませんが、これに触れることはオブジェクト指向理解の一助となるかと思います。
特に、なぜ継承が不要なのか、についてはデザインパターンにふれる方が説明をされるよりもわかりやすいかと思います。
以上となります。