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 関係 = 継承」というふうに言われることがありますが、ちょっと違います。
似てはいますが、同一ではありません。
is-a 関係とは、例えば
  • 猿と人は哺乳類の一種
    哺乳類と爬虫類は動物の一種
    動物と植物は生物の一種
  • トランペットとトロンボーンは金管楽器の一種
    金管楽器と木管楽器は管楽器の一種
    管楽器と弦楽器は楽器の一種
のようなカンジのものです。
そして、これが分類法による分析です。
このように、分類法とは、物事を分類していくことで、その物事の本質を掴もうとする分析方法です。
物事をありのままにとらえ、その性質に従って分類していくと、物事同士の共通点が見えてきますね。
共通点を慎重に選り分けていった中に、本質が見えてくるのではないかという考え方なわけです。

分割による分析

has-a というのは、以下のような関係を表しています。
A has a B.
日本語で言うと、A は B を含んでいる (has a) ということですね。
これは、分割法によって物事を捉えようとすることを示唆しています。
「has-a 関係 = 包含」と言われることがありますが、これも違います。
is-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 とか言うときには、そのことをちょっと思い出してください。

2 件のコメント:

  1. 大変参考になりました。
    継承と集約、コンポジションは設計でいつも迷います。ややもするとプログラマの人たちは雑駁な関数群の海を作ってしまいます。
    自分もそうであったように人間の本性でもあるのでしょうが。
    重箱の隅的で申し訳ないのですが。
    ほ乳類とは忠類を
    哺乳類 爬虫類 
    のようにされた方が分類表記としては正しいと思われます。内容が高度なだけに、ほ乳類という読みはあっても、どう物という表記がないように文にした場合のことですが、本文の格調のためにもと、さしでがましいことですが修正されてはと存じます。

    返信削除
  2. ご指摘、ありがとうございます。
     哺乳類の哺が平仮名になっていたことについては、おっしゃるとおり表記の問題ですが、"は忠類"は単なる誤字ですね。
     修正させていただきます。
    修正しても意味、内容には変化がないことから、取り消し線等で以前の内容を残したりはせず、直接変更します。

    返信削除

Related Posts Plugin for WordPress, Blogger...