2007年07月28日

is-a関係とhas-a関係: 継承と包含

 あるオブジェクトが、他のオブジェクトを継承しているのか包含しているのか。
一見継承と包含は全く別物ですが、これが意外と判断が難しい場合があります。

 is-a関係、has-a関係という言葉は、そういう場合の判断の指針として使われるものです。

コンテンツ

  1. はじめに
  2. 分類による分析
  3. 分割による分析
  4. 分類法と分割法をオブジェクト指向で表現
  5. 本質はアプローチ

はじめに

 最初に知っておいていただきたいのは、そもそも、is-a関係とhas-a関係というのは、オブジェクト指向に限った話ではないということです。
これらは、一般的な物事の本質を捉えるための分析のしかた、考え方についてのメタファです。

分類による分析

 is-aというのは、以下のような関係を表しています。
A is a B.
日本語で言うと、Aは(is)Bの一種(a)ということになります。
これは、分類法によって物事を捉えようという試みを示唆しています。
「is-a関係 = 継承」というふうに言われることがありますが、ちょっと違います。

 例えば
  • 動物と植物は生物の一種
    哺乳類と爬虫類は動物の一種
    猿と人は哺乳類の一種
  • 管楽器と弦楽器は楽器の一種
    金管楽器と木管楽器は管楽器の一種
    トランペットとトロンボーンは金管楽器の一種
のようなカンジです。

 このように、分類法とは、物事を分類していくことで、その物事の本質を掴もうとする分析方法です。
物事をありのままにとらえ、その性質に従って分類していくと、物事同士の共通点が見えてきますね。
共通点を慎重に選り分けていった中に、本質が見えてくるのではないかという考え方なわけです。

分割による分析

 has-aというのは、以下のような関係を表しています。
A has a B.
日本とで言うと、AはBを含んでいる(has a)ということですね。
これは、分割法によって物事捉えようとすることを示唆しています。
「has-a関係 = 包含」と言われることがありますが、これも違います。

 例えば
  • 人間は頭、腕、脚、胴体を含んでいる
    腕は上腕、下腕、手を含んでいる
    手は手の甲、手のひら、指を含んでいる
  • トランペットはマウスピース、パイプ、トリガー、バルブ、ベルを含んでいる
    パイプはマウスパイプ、第一抜き差し管、主抜き差し管を含んでいる
のようなカンジです。

 このように、分割法は、より小さく物事を分割していくことで、その物事の本質を掴もうとする分析方法です。
物事というのは、そのままでは複雑なので、適切に切り分けることで単純化し、より明確にしよう。
そうすることで、本質が見えてくるのではないかという考え方です。

 このように、分類法と分割法は、物事を分析する際の、2通りの全く異なったアプローチです。
どういう場合にどちらを採用しなければならないという決まりはありません。
あなたが、そのときどきで都合がいいと思う方を選択して、適用してください。

is-aとhas-aに話を戻しましょう。

分類法と分割法をオブジェクト指向で表現

 分類法をオブジェクト指向で表現するのに、最も都合がいい方法が、継承です。
サブクラスAとスーパークラスBの関係は、まさにAはBの一種であるということを表現していますね。
分類法の考え方そのままです。
「is-aは継承」とよく言われる理由は、ここにあります。

 でも、この言葉を文字通りに受け取らないでください。
本当の意味は、「is-aで表される分類法での分析は、継承で表現するのが一番適切」ということなのです。

 同じように、分割法をオブジェクト指向で表現するのに、最も都合がいい方法が、包含です。
クラスAと、その属性に含まれるクラスBの関係は、まさにAはBを含んでいるということを表現していますね。
分割法の考え方そのままです。
「has-aは包含」とよく言われる理由は、ここにあります。

 でも、この言葉を文字通りに受け取らないでください。
本当の意味は、「has-aで表される分割法での分析は、包含で表現するのが一番適切」ということなのです。

本質はアプローチ

 結局、オブジェクト思考も一つの道具にすぎません。
大事なのは、あなたの分析や設計なのです。
分類法や分割法は、分析/設計のための有効なアプローチですが、継承や包含は単なる表現方法でしかありません。
is-aとhas-aの違いは、継承か包含かというような、実装方法の違いではなく、もっと根本的な、アプローチの違いなのです。

 本質は分類法、分割法にあり、継承や包含は表層にすぎない。
is-aとかhas-aとか言うときには、そのことをちょっと思い出してください。
posted by craftsman at 16:26 | 東京 ☀ | Comment(2) | TrackBack(0) | 発展編
この記事へのコメント
大変参考になりました。
継承と集約、コンポジションは設計でいつも迷います。ややもするとプログラマの人たちは雑駁な関数群の海を作ってしまいます。
自分もそうであったように人間の本性でもあるのでしょうが。


重箱の隅的で申し訳ないのですが。
ほ乳類とは忠類を
哺乳類 爬虫類 
のようにされた方が分類表記としては正しいと思われます。内容が高度なだけに、ほ乳類という読みはあっても、どう物という表記がないように文にした場合のことですが、本文の格調のためにもと、さしでがましいことですが修正されてはと存じます。
Posted by 絆地 治 at 2010年01月03日 16:52
ご指摘、ありがとうございます。

 哺乳類の哺が平仮名になっていたことについては、おっしゃるとおり表記の問題ですが、"は忠類"は単なる誤字ですね。

 修正させていただきます。
修正しても意味、内容には変化がないことから、取り消し線等で以前の内容を残したりはせず、直接変更します。
Posted by craftsman at 2010年01月06日 10:39
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。