Index: [Article Count Order] [Thread]

Date:  Fri, 03 Feb 2006 11:31:47 +0900
From:  KAMO Masahiko <*****@**.*******.***>
Subject:  [oosquare-ml:04725] Re: UMLでの集合表現について
Sender:  *******************@**.*******.**.**
To:  オブジェクトの広場メーリングリスト <***********@**.*******.**.**>
Message-Id:  <**************.***********@*****.***.***.*******.***>
In-Reply-To:  <008301c62776$b977acd0$********@********>
References:  <00a901c62677$e36998f0$********@********>	<**************.****.********@*******.******.**.**>	<008301c62776$b977acd0$********@********>
X-Mail-Count: 04725

加茂です.
長文ですみません.

> 上記の駅のモデルで感じたのは、駅という特徴を持ちつつ、快速の停車駅
> という特別な特徴をもたせるということで汎化関係であれば、
> 自分としては納得がいったのですが、そういう認識はすこし違って
> いるのでしょうか?

いえ,それであっていると思います.
そういった認識には特に異論を唱えたつもりはないです.

私が言おうとしたのは,

  - オブジェクトを特徴ごとに分けて整理するのがクラスやクラス図の目的
  - オブジェクトの特徴を考えるとき,クラスに属するオブジェクトの
    集合・部分集合関係が重要なので,
    集合間の関係のうち汎化関係(≒集合・部分集合関係)だけ
    さくっとクラス図でかける.
    クラス図で集合・部分集合関係だけなら書ける
  - でもオブジェクト(要素)の特徴を考えずに
    クラス(集合)の集合・部分集合関係以外の関係(AND,OR,XOR)
    を表すという目的にクラス図を無理に使うのはあまり適切ではないかなと思った
    
ということです.

> これは2重継承になっているということでしょうか?
> (認識が違っていたらすみません)
> オブジェクト指向としては多重継承は良くないと
> 聞いたことがある(どちらの親の機能を継承するか
> あいまいになる為)のですが、ここでは特に
> 問題は起きないのでしょうか?

はい,この場合問題にはなりません.

まず,多重継承にはダメな多重継承とそうではない多重継承があります.
継承は大きく分けると
  - インタフェース継承
  - 実装継承
の二つに分けられますが,前者での多重継承やOK,後者での多重継承はNGです.

インタフェース継承というのは,
「どんなサービスを他のクラスに向けて提供するか」という
外部向けの特徴だけをサブクラスが引き継ぐことです.
UMLでは 実現関係 と呼んでいるもののことです.
インタフェース継承の場合,多重継承をしても大きな問題が出ることはありません.
Javaでもinterfaceはextendsの後ろにたくさんインタフェースを書けたり
classはimplementsのうしろにたくさんインタフェースを書けたりするのは,
インタフェース継承なら多重継承はやってもいいとみなされているからと
思ってください.

実装継承というのは
「あるサービスをどうやって実装するか」という
内部的な特徴をサブクラスが引き継ぐことです.
実装継承の場合,例えば同じ親クラスを持つ二つのクラスを親クラスに持つクラス,
図で書くと以下のDのようなクラスを作ると
  A<|----B<|----D
  A<|----C<|----D
ややこしいことが起こります.
興味がありましたら菱形継承とか多重継承とか実装継承とかの
キーワードで調べてみてください.
おそらくC++での解説がされている記事が見つかると思います.
Javaでclassがextendsの後ろにclassを一個しかかけないのは
実装継承はやっちゃだめとみなされているからだと思ってください.

一般に多重継承がだめ,といわれているのは
実装継承で問題が起きるからという理由からです.

次に,クラス図中に汎化関係が出てきたとき,
それが実装継承になる場合とならない場合があります.
ソフトウェア開発においてクラス図はおおきく
  - 分析結果のクラス図
  - 設計結果のクラス図
に分けられますが,前者に出てくる多重継承は問題にならず,
後者に出てくる実装継承の多重継承は問題になります.

分析結果のクラス図は問題を把握するために
自分が見たこと考えたことをあるがままに書いていきます.
ソフトウェアでどう実装するかはとりあえずおいておき,
問題を把握することを重視します.
必要とあらば素直に自分の理解を書き留めるために
多重継承も使っても問題ありません.
なぜならこの段階で書かれた汎化関係が
実装されるときに実装継承になるとは限らないからです.

設計結果のクラス図は分析結果のクラス図を受けて,
どうやってソフトウェアとして実際に実装するかを書きます.
設計結果のクラス図で出てくる汎化関係が多重継承になっていたらアウトです.
実装継承で多重継承をすることになってしまいます.
この段階では分析結果のクラス図で多重継承が出ていた場合に
分析結果のクラス図の多重継承がインタフェース継承だけに収まるように
インタフェース継承(実現関係)や実装継承や集約を使って設計しなければいけません.

で,導きたい結論なのですが,
「分析結果のクラス図で多重継承を使うこと」=「実装継承で多重継承を使うことは」
ではない,ということです.
私のクラス図は問題を分析した結果を素直に書いたものです.
菊地さんが提示された問題を分析した結果のクラス図であり,
実装を考えた設計したものではありません.
なのでこの段階でのクラス図で多重継承を使うのは問題ありません.

以上

---
加茂 昌彦 (KAMO Masahiko)
*****@**.*******.***

-------------------------------------
オブジェクトの広場
http://www.ogis-ri.co.jp/otc/hiroba/