- PR -

インターフェイスによる継承と抽象化クラスによる継承の使い分け

投稿者投稿内容
IIJIMAS
ベテラン
会議室デビュー日: 2006/12/06
投稿数: 77
投稿日時: 2007-09-03 14:31
引用:

未記入さんの書き込み (2007-09-03 13:57) より:
いくら例を出されてもねえ。それってあなたのインターフェイス/抽象クラスの決定スタンスに合わせて例を出しているだけでしょう?私はもっと広範にインターフェイスを使ってよいと考えています。実際、単一継承という言語仕様の制限によって、あなたのスタンスに合わないものをインターフェイスとして実装しなければいけない事実をあなた自身で見つけられるはずですよ?


値型や既に何かを継承しているクラスのことですか。
もともと自分の決定スタンスに合わないものを除外しているつもりはありません。
引用:

・抽象クラス:ジグソーパズル 1ピースの一辺の形状
・サブクラス:ジグソーパズルの 1ピースの輪郭
・集約クラス:ジグソーパズルの 1ピース(輪郭をあらわすメンバー 4つを保持している north, east, west, south)

という設計もできますよね。あなたの設計では 4辺の形状組み合わせで実装クラスが膨大に膨れ上がってしまいますので、この場合なら集約を使ったほうがいいでしょう。無理にインターフェイス、抽象クラス、実装クラスを使って例示しようとするから設計自体がおかしくなっているんです。


「膨れ上がる」というのがよくわかりません。
引用:

「くだもの」インターフェイスを実装した「りんご」クラス。


もともと私は「has a capability」「has a role」「has a function」「has a responsibility」に限定しているわけではないのですが(だからこそ知りたいと書きました)、それはたとえば「has a role」とも考ることができると思います。たぶん「is a」と仰りたいのだと思いますが。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2007-09-03 15:18
引用:

「膨れ上がる」というのがよくわかりません。


どういうコードを書こうと思っていますか?「一辺をあらわすもの」をインターフェイス(抽象クラス)として「四辺を持つピース」を(集約を使わずに)実装するのは非常に面倒なことになると思いますけど。

引用:

もともと私は「has a capability」「has a role」「has a function」「has a responsibility」に限定しているわけではないのですが


あれ? インターフェイスは「・・・できるもの」だとか言っていませんでしたか?

引用:

それはたとえば「has a role」とも考ることができると思います。たぶん「is a」と仰りたいのだと思いますが。


よりによって「has a role」ですか。私は英語は良くわかりませんが(あなたの紹介してくれた Interfaces vs. Abstract Base Classes も当然読んでません)、「has a role」はもっともゆるい表現じゃないですか? 私の感じ方として「has a role」は多態性を持っていること(つまり抽象クラス派生でもインターフェース実装でもすべてにあてはまる)、言語仕様として当たり前のことを言っているだけのように感じます。

「has a capability」「has a role」「has a function」「has a responsibility」は、すべて「a kind of」ですよ。「has a role」もっとも「a kind of」に近いと思います。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2007-09-03 17:40
ジグソーパズルの例はちょっと良く分からなかったのですが、インターフェイスは「〜として振舞う」と考えると自然に捉えられるのではないでしょうか。
これは、インターフェイスがオブジェクトの振る舞いを定義する構文であることからも自然だと思います。
先ほどの私の「無名のインターフェイス」をこれで考えてみると、「鳥は鳥として振舞う」ということです。当たり前ですが。
「無名のインターフェイス」ってちょっと意味が通りづらいですね。以降「暗黙のインターフェイス」と呼ぶことにします。

引用:

未記入さんの書き込み (2007-09-03 13:57) より:
「くだもの」インターフェイスを実装した「りんご」クラス。


引用:

IIJIMASさんの書き込み (2007-09-03 14:31) より:
たぶん「is a」と仰りたいのだと思いますが。


私の日常生活ドメイン(問題領域)では、りんごはくだものという括りですので、IIJIMASさんの仰る「is a」の関係として認識されています。
ですので、未記入さんは「is a」の関係でもインターフェイスが使えるのだという主張をしているのだと受け取りました。
上の「暗黙のインターフェイス」の話の通り、「is a」の時にもインターフェイスを引き継いでいますが、「is a」はインターフェイスだけでは足りないというのが私の考えです。つまり継承するべきだということです。
引用:

未記入さんの書き込み (2007-09-03 15:18) より:
「has a capability」「has a role」「has a function」「has a responsibility」は、すべて「a kind of」ですよ。


言っている意味は分かります。
飛行機が「乗り物」クラスから継承されて、かつ鳥と同じ「飛ぶ」インターフェイスを実装している場合に、飛行機は乗り物の一種であると同時に「飛ぶもの」というグループの一種だと考えることもできるということですよね。
ですが、「飛ぶもの」グループというものを継承のツリー構造でのグループ分けと同じレベルで認識する必要があるでしょうか。
未記入さんは、言語仕様の制限によって継承の代替としてインターフェイスがあるとお考えのようです。確かにそういう面あるでしょう。
しかし、あるひとつの視点から問題領域を捉えた時に、主となる継承のツリー構造が複数あり、多重継承を使いたくなるような場面には私は一度も遭遇したことがありません。そして例も思いつきません。
例えば動物の生物学的な視点から見たときに、イルカは哺乳類ですが泳ぐという魚類がよく持つ機能を持っています。
タイやヒラメも泳ぎますし、イサキも泳ぐわけですが、これらが「泳ぐもの」グループを形成しているという捉え方をこの問題領域ではするでしょうか。
そういう分類ができるかできないかではなく、属だの目だの類だのと分類している問題領域で、それと同じレベルの分類としてするほどのものと認識されているかということです。
「こいつは泳ぐ/泳がない」という、それぞれのクラスに付く属性的な扱いが適当ではないでしょうか。これは主となるグループ階層構造を強調するという意味合いもあります。
これは視点によりですので、「泳ぐもの」という分類が常に間違っているといっているわけではありません。
例えば子供の読み物で「陸の生き物」「海の生き物」という分類で分けて本を作るのは十分考えられます。
その場合は、哺乳類だとか魚類だとかいったことが属性的な扱いになるでしょう。
「いるかは魚みたいに泳ぐけど、魚じゃなくて君達と同じほにゅうるいなんだ」
といったような。

[ メッセージ編集済み 編集者: 一郎 編集日時 2007-09-03 17:53 ]
未記入
会議室デビュー日: 2007/06/05
投稿数: 5
投稿日時: 2007-09-03 17:42
いってることの是非はともかく。

未記入氏の感じの悪さが理解できん。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2007-09-03 18:08
引用:

飛行機は乗り物の一種であると同時に「飛ぶもの」というグループの一種だと考えることもできるということですよね。


はい、そうです。

引用:

ですが、「飛ぶもの」グループというものを継承のツリー構造でのグループ分けと同じレベルで認識する必要があるでしょうか。(省略)あるひとつの視点から問題領域を捉えた時に、主となる継承のツリー構造が複数あり、多重継承を使いたくなるような場面には私は一度も遭遇したことがありません。そして例も思いつきません。


継承ツリーにどちらを入れるか迷うこともあるかと思いますが・・・。

たとえば、カラスや戦闘機が戦う戦略ゲームを作るとしましょう。ユニットには「地上ユニット」と「飛行ユニット」があります。また別の視点では「小型ユニット」と「大型ユニット」があります。飛行ユニットは他のユニットを飛び越えられるとか、大型ユニットは戦略マップ上で 2x2 マス占有するとかそんな感じです。

さて、継承ツリーはどうしますか?

コード:
ユニット-----地上ユニット
          |
          +--飛行ユニット


として「大型属性」をインターフェイスとすることもできます。

コード:
ユニット-----小型ユニット
          |
          +--大型ユニット


として「飛行属性」をインターフェイスとすることもできます。

どちらも同程度の重要性を持ちませんか? 明快な is-a がひとつだけ存在するとはいえないこともあります。

引用:

未記入さんは、言語仕様の制限によって継承の代替としてインターフェイスがあるとお考えのようです。


いいえ、逆です。言語仕様によってインターフェイスを使わざるを得ないのではなく、言語仕様を意識しない設計レベルでは、すべてインターフェイスであるということです。コードを書くときになって、継承によってコードの再利用ができる言語なら、インターフェイスのうちのひとつをコード削減のためにクラスにすればいいと思います。

引用:

例えば動物の生物学的な視点から見たときに、(省略)


たとえ話は、もう結構ですよ。あなたたちは持論を補強するために、明快な直系(is-a)がひとつしか存在しない事例を持ち出してきているだけでしょう。設計レベルではインターフェイスでいいんです。最後にコードを再利用しやすいようにクラスに置き換えたりすれば。もちろん、直感的な is-a がコードの重複を減らしやすいという傾向があるのも事実ですから、直感的な is-a をはじめからクラスとして継承ツリーを作ってもいいと思います。(実際のところ、私もそうやって設計していますから。)

だからといって、それがインターフェイスの役割/使用目的を(has a 〜)に制限することにはならないはずです。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2007-09-03 18:13
引用:

未記入さんの書き込み (2007-09-03 17:42) より:
いってることの是非はともかく。

未記入氏の感じの悪さが理解できん。


そうだね。俺も↓の未記入の感じの悪さは理解できん。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=39164&forum=7
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=38736&forum=7&start=31
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=40349&forum=7&start=10

[ メッセージ編集済み 編集者: ぶさいくろう 編集日時 2007-09-03 18:17 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-09-03 19:08
インターフェースや抽象クラスを、厳密に定義しなければならないのでしょうか。

C++ではインターフェースを定義出来ませんし、C#では複数のスーパー クラスを持てないところから、インターフェースを実装したスーパー クラスを作るなどの工夫をします。
言語仕様の制約の下、作りやすいもの、自己流定義に近いものを選ぶ、じゃダメですか?
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-09-03 20:51
うーん、未記入さんのおっしゃっていることと
他の方のおっしゃってることって本質的に何も変わらず、
言葉の言い換えにしか見えないのですが。

引用:

未記入さんの書き込み (2007-09-03 18:08) より:
さて、継承ツリーはどうしますか?

コード:
ユニット-----地上ユニット
          |
          +--飛行ユニット


として「大型属性」をインターフェイスとすることもできます。

コード:
ユニット-----小型ユニット
          |
          +--大型ユニット


として「飛行属性」をインターフェイスとすることもできます。

どちらも同程度の重要性を持ちませんか? 明快な is-a がひとつだけ存在するとはいえないこともあります。



この場合なら、どちらもインタフェースで実装するでしょうね。
でも、ここにはそもそもis-aの対象となるクラスが書かれていないので当たり前のような気がします。

地上/飛行/小型/大型どれもインターフェースで、
ユニット(抽象クラスですね)を継承した具象クラスを挙げるなら、
戦車ユニット(地上、大型)、歩兵ユニット(地上、小型)みたいな感じですかね。
地上/飛行/小型/大型もあるオブジェクトの一部の性質でしかありません。

しかし、地上ユニット、飛行ユニット、小型ユニット、大型ユニットと
命名をしたことでユニットに対してそれぞれのクラスはis-aの関係になりました。
でも、この命名ならこれらはインタフェースではなく抽象クラスだと思いますよ。

各人の持つプログラミング言語のバックボーンが違うから、
設計時の命名の仕方が違うということなんだろうと勝手に推測しています。

スキルアップ/キャリアアップ(JOB@IT)