オブジェクト指向は,現実世界をそのままプログラムに表現できると言われることがありますが,それは正しい理解ではありません。オブジェクト指向プログラミングの仕組みと現実世界は「似て非なるもの」であり,「プログラミング技術」と「汎用の整理術」の二つの側面があります。オブジェクト指向は,それ自体が複雑で難しいものではなく,あくまでソフトウエア開発をラクにする技術にすぎません。

 オブジェクト指向はしばしば,とっつきづらく難しい技術と言われます。その理由の一つには,対象とする分野が広く,それぞれに深みがあることが挙げられます。しかし,それ以上にこの技術を難しくしている落とし穴とも言うべき原因が二つあると筆者は考えています。それは比喩(ひゆ)を乱用する説明の仕方の問題と,「もの中心」を意味するコンセプト自体の問題です。

 そこでこの記事では,「オブジェクト指向という言葉をよく聞くけど,実際どんなものかよくわからない」という方のために,初心者/入門者が陥りやすい落とし穴を明確にしながら,オブジェクト指向の全体像を説明します。余計な先入観やまぎらわしいたとえ話に惑わされなければ,オブジェクト指向そのものはそれほど難しい技術ではないことを理解していただきたいと思います。

オブジェクト指向が登場した背景

 オブジェクト指向は,英語では“object oriented”であり,「もの指向」「もの中心」といった意味を持ちます。一言で表現するなら「オブジェクト(もの)中心に考えるソフトウエア開発手法」と言えるでしょう。

 従来の開発手法は,ソフトウエアが実現する「機能」に着目しました。最初に全体として実現する機能を定義し,それを徐々に細かい機能に分割していくのが基本的なやり方です。この手法は「構造化分析/設計手法」として体系化されており,長い間主流として使われてきました。

 オブジェクト指向では全体の機能を一枚岩ととらえずに,データと手続きを持った「オブジェクト」の集まりとしてとらえます。ソフトウエア全体として機能を実現するだけでなく,保守性や再利用性に配慮して,個々の部品の独立性も重視するわけです。

 こうした考え方が重要になった背景には,ソフトウエアが大規模で複雑になったことがあります。以前のソフトウエア開発では,毎回ほとんどゼロからプログラムを作り直していました。しかしそうした方法では,品質の高いソフトウエアを短期間で作ることは困難なため,既存の部品を再利用することが重要になってきました。また,いったん作ったソフトウエアに修正を加えて長く使い続けるケースも増えてきました。ソフトウエアを保守しやすくするには,個々の部品の独立性を高くして,全体の見通しを良くし,修正の影響範囲を局所化する必要があります。こうしたニーズからオブジェクト指向が注目されるようになりました。

正しい理解を妨げる落とし穴

 オブジェクト指向という考え方は,目に見える「もの」を中心に現実世界を識別する人間にとって,自然な考え方であると説明されることもあります。にもかかわらず,オブジェクト指向は難しい技術だと言われます。その理由の一つとして,オブジェクト指向がソフトウエア開発の幅広い分野を対象にしていることが挙げられるでしょう。抽象的な考え方が求められるから難しいのだという意見を聞くこともあります。

 しかし筆者には,どうもそれだけが原因とは思えません。筆者は過去に,オブジェクト指向と哲学を対比する説明や,「オブジェクト指向を使えば現実世界をそのままプログラムに表現できる」といったちょっと不思議な説明を聞く機会が何度かありました。そうした聞き手の意表を突く話は,何かおかしいと感じながらも,思わず受け入れてしまいがちです。そうした経験から考えると,難しいというよりも混乱していると解釈するほうが適切に思えます。

 以降では,そうした混乱を引き起こしている原因として「比喩の乱用」と「強力過ぎるコンセプト」の二つの問題を説明します。この二つは,オブジェクト指向の正しい理解を妨げる落とし穴と言えるでしょう。「オブジェクト指向は難しくてよくわからない」と思っている方は,ぜひその先入観を捨てて,白紙の気持ちで読み進めてください。

比喩の乱用が混乱を引き起こす

 一つ目の落とし穴は「比喩の乱用」です。これは,技術そのものと言うよりも,説明の仕方に起因する問題と言えるでしょう。

 オブジェクト指向プログラミングの仕組みは,しばしば現実世界と対比して説明されます。そして,こうした説明が理解を助けるためのたとえ話であることを明示しないケースをよく見かけます。例えば,次のような説明です。

説明1-クラスとインスタンス
 「クラス」は種類で,「インスタンス」は具体的なものを表す。犬を例に取れば,一般的な“犬”が「クラス」で,“タロー”“ポチ”“マル”などの具体的な犬が「インスタンス」に相当する。犬が共通に持っている“名前”“年齢”などの性質を「属性」と呼び,“鳴く”“エサを食べる”“寝る”といった共通な振る舞いを「メソッド」と呼ぶ(図1)。

図1●クラスとインスタンス。一般的な“犬”が「クラス」で,“タロー”“ポチ”“マル”などの具体的な犬が「インスタンス」に相当すると説明されることがある
図1●クラスとインスタンス。一般的な“犬”が「クラス」で,“タロー”“ポチ”“マル”などの具体的な犬が「インスタンス」に相当すると説明されることがある

説明2-メッセージ・パッシング
 オブジェクト指向言語を使って書かれたプログラムは,インスタンス同士がメッセージを送り合って動作する。この仕組みは,飼い主が飼い犬に対して“鳴け”とメッセージを送ると“ワン”と応える様子に相当する(図2)。

図2●メッセージ・パッシングのイメージ。飼い主が飼い犬に対して“鳴け”とメッセージを送ると“ワン”と応える様子に相当するというが,現実にはメッセージに応えない犬もいるだろうし,命令されなくても吠える場合もある
図2●メッセージ・パッシングのイメージ。飼い主が飼い犬に対して“鳴け”とメッセージを送ると“ワン”と応える様子に相当するというが,現実にはメッセージに応えない犬もいるだろうし,命令されなくても吠える場合もある

 こうした説明は,オブジェクト指向プログラミングの仕組みを直感的に理解するのには適しています。しかし,実際にはこの説明は正しくありません。オブジェクト指向のプログラムの世界では,犬クラスにnew指令を送ることで個々のインスタンスが作られますが,現実世界の犬が生まれるのは妊娠したメス親が出産するからです。また,プログラムのインスタンスは,メッセージを受けると必ず仕事をします(反対に,メッセージを受けるまでは,ただじっと待ち続けています)。これに対して,現実世界の犬は,“鳴け”と命令されても機嫌が悪ければ飼い主を無視するでしょうし,命令されなくても鳴きたければ自分の意志で勝手に鳴くでしょう。