
![]() |
|||
|
クラス同士の類似性に着目すると、階層構造になります。 |
![]() |
|||
| このトピックでは次の用語を覚えます: | |||
|
|||
![]() |
|||
|
テリア犬とポメラニアンと猿と人間をを分類してみましょう。 まず、テリアとポメラニアンは犬の一種です。「一種である」ということは、どちらも「犬」としての基本機能を有しているということです。例えば、「ほえる」「食べる」「四つ足で歩く」「犬歯がある」「鼻が良い」などのような機能です。このような関係をオブジェクト指向では継承という言葉で表現します。つまり、「テリアとポメラニアンは犬を継承している」などと言います。 同じように、犬と猿と人間は動物の一種です。言い換えると、犬と猿と人間は動物を継承しています。べつに進化の系統図を作ろうというわけではないので、人間を猿の一種とはみなしません。人間は猿の「バナナが好き」を継承していませんから(!)。 動物は生き物を継承しています。植物もそうですね。 |
|||
|
上記の継承を図にすると、次のような階層構造になります。下のものは上のものの機能を継承しています。この図を継承図とかクラス階層図などと呼びます。
上位のクラスは下位のクラスの共通機能を抜き出したものであると言えます。例えばテリアと人間は、動物としての基本機能(「食べる」「呼吸する」など)を共通に持っていますね。ですからどちらのクラスのインスタンスも動物としての基本機能を同じように実行できる必要があります。そしてこれらの機能は各々のクラスで定義されているのではなく、上位の動物クラスで定義されています。 逆に考えると、下位のクラスは上位のクラスにいくつかの機能を付け足したものです。これが何を意味するかというと、「クラス階層は作る量を減らすのに役立つ」と言うことです。例えば新たに「ドーベルマン」クラスが必要になったときは、もうゼロから作る必要はなく、「犬」クラスを継承してほんの少しドーベルマン特有の機能を付け加えるだけです。コンポジションだけでは解決できなかった無駄が、継承という仕組みによってなくなるのです。 |
|||
|
しかし、誤ったクラス階層は非常に困った結果を招きます。下図はエンジニアと画家と音楽家を分類しようとした例ですが、間違いです。
なぜ間違いかというと、例えば、エンジニアは人間の一種ではないからです。エンジニアは人間の役割のひとつです。エンジニアで、かつ画家という人もいるはずです。この分類方法ではレオナルド・ダ・ビンチはどのクラスのインスタンスにもなれません! 同様に、アーティストも人間の一種ではありません。 ただし、画家と音楽家はアーティストの一種ですから、図中の左下の3つのクラスの階層は正しいですね。 |
|||
|
画家で、かつエンジニアである人のオブジェクトを実現するには、コンポジションを使います。下図は画家でエンジニアの「太郎」という人のオブジェクトの構造です。画家としての技術を実装したオブジェクトと、エンジニアの技術を実装したオブジェクトを、それぞれ内部に持っています。
|
|||
|
このように、オブジェクトは継承とコンポジションによって明確かつ効率的に表現することができます。継承をコンポジションと区別するために、Is-A 関係とか A-Kind-Of 関係という言葉があります(どちらも同じ意味です)。 Is-A/A-Kind-Of 関係: Has-A/Part-Of 関係と区別して、良く理解しておきましょう。 |
|||
(「オブジェクト指向のはなし」は1999年2月から2000年4月にかけて作成されたコンテンツです。)