- - PR -
インターフェイスによる継承と抽象化クラスによる継承の使い分け
投稿者 | 投稿内容 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-09-03 14:31
値型や既に何かを継承しているクラスのことですか。 もともと自分の決定スタンスに合わないものを除外しているつもりはありません。
「膨れ上がる」というのがよくわかりません。
もともと私は「has a capability」「has a role」「has a function」「has a responsibility」に限定しているわけではないのですが(だからこそ知りたいと書きました)、それはたとえば「has a role」とも考ることができると思います。たぶん「is a」と仰りたいのだと思いますが。 | ||||||||||||||||||||||||
|
投稿日時: 2007-09-03 15:18
どういうコードを書こうと思っていますか?「一辺をあらわすもの」をインターフェイス(抽象クラス)として「四辺を持つピース」を(集約を使わずに)実装するのは非常に面倒なことになると思いますけど。
あれ? インターフェイスは「・・・できるもの」だとか言っていませんでしたか?
よりによって「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」に近いと思います。 | ||||||||||||||||||||||||
|
投稿日時: 2007-09-03 17:40
ジグソーパズルの例はちょっと良く分からなかったのですが、インターフェイスは「〜として振舞う」と考えると自然に捉えられるのではないでしょうか。
これは、インターフェイスがオブジェクトの振る舞いを定義する構文であることからも自然だと思います。 先ほどの私の「無名のインターフェイス」をこれで考えてみると、「鳥は鳥として振舞う」ということです。当たり前ですが。 「無名のインターフェイス」ってちょっと意味が通りづらいですね。以降「暗黙のインターフェイス」と呼ぶことにします。
私の日常生活ドメイン(問題領域)では、りんごはくだものという括りですので、IIJIMASさんの仰る「is a」の関係として認識されています。 ですので、未記入さんは「is a」の関係でもインターフェイスが使えるのだという主張をしているのだと受け取りました。 上の「暗黙のインターフェイス」の話の通り、「is a」の時にもインターフェイスを引き継いでいますが、「is a」はインターフェイスだけでは足りないというのが私の考えです。つまり継承するべきだということです。
言っている意味は分かります。 飛行機が「乗り物」クラスから継承されて、かつ鳥と同じ「飛ぶ」インターフェイスを実装している場合に、飛行機は乗り物の一種であると同時に「飛ぶもの」というグループの一種だと考えることもできるということですよね。 ですが、「飛ぶもの」グループというものを継承のツリー構造でのグループ分けと同じレベルで認識する必要があるでしょうか。 未記入さんは、言語仕様の制限によって継承の代替としてインターフェイスがあるとお考えのようです。確かにそういう面あるでしょう。 しかし、あるひとつの視点から問題領域を捉えた時に、主となる継承のツリー構造が複数あり、多重継承を使いたくなるような場面には私は一度も遭遇したことがありません。そして例も思いつきません。 例えば動物の生物学的な視点から見たときに、イルカは哺乳類ですが泳ぐという魚類がよく持つ機能を持っています。 タイやヒラメも泳ぎますし、イサキも泳ぐわけですが、これらが「泳ぐもの」グループを形成しているという捉え方をこの問題領域ではするでしょうか。 そういう分類ができるかできないかではなく、属だの目だの類だのと分類している問題領域で、それと同じレベルの分類としてするほどのものと認識されているかということです。 「こいつは泳ぐ/泳がない」という、それぞれのクラスに付く属性的な扱いが適当ではないでしょうか。これは主となるグループ階層構造を強調するという意味合いもあります。 これは視点によりですので、「泳ぐもの」という分類が常に間違っているといっているわけではありません。 例えば子供の読み物で「陸の生き物」「海の生き物」という分類で分けて本を作るのは十分考えられます。 その場合は、哺乳類だとか魚類だとかいったことが属性的な扱いになるでしょう。 「いるかは魚みたいに泳ぐけど、魚じゃなくて君達と同じほにゅうるいなんだ」 といったような。 [ メッセージ編集済み 編集者: 一郎 編集日時 2007-09-03 17:53 ] | ||||||||||||||||||||||||
|
投稿日時: 2007-09-03 17:42
いってることの是非はともかく。
未記入氏の感じの悪さが理解できん。 | ||||||||||||||||||||||||
|
投稿日時: 2007-09-03 18:08
はい、そうです。
継承ツリーにどちらを入れるか迷うこともあるかと思いますが・・・。 たとえば、カラスや戦闘機が戦う戦略ゲームを作るとしましょう。ユニットには「地上ユニット」と「飛行ユニット」があります。また別の視点では「小型ユニット」と「大型ユニット」があります。飛行ユニットは他のユニットを飛び越えられるとか、大型ユニットは戦略マップ上で 2x2 マス占有するとかそんな感じです。 さて、継承ツリーはどうしますか?
として「大型属性」をインターフェイスとすることもできます。
として「飛行属性」をインターフェイスとすることもできます。 どちらも同程度の重要性を持ちませんか? 明快な is-a がひとつだけ存在するとはいえないこともあります。
いいえ、逆です。言語仕様によってインターフェイスを使わざるを得ないのではなく、言語仕様を意識しない設計レベルでは、すべてインターフェイスであるということです。コードを書くときになって、継承によってコードの再利用ができる言語なら、インターフェイスのうちのひとつをコード削減のためにクラスにすればいいと思います。
たとえ話は、もう結構ですよ。あなたたちは持論を補強するために、明快な直系(is-a)がひとつしか存在しない事例を持ち出してきているだけでしょう。設計レベルではインターフェイスでいいんです。最後にコードを再利用しやすいようにクラスに置き換えたりすれば。もちろん、直感的な is-a がコードの重複を減らしやすいという傾向があるのも事実ですから、直感的な is-a をはじめからクラスとして継承ツリーを作ってもいいと思います。(実際のところ、私もそうやって設計していますから。) だからといって、それがインターフェイスの役割/使用目的を(has a 〜)に制限することにはならないはずです。 | ||||||||||||||||||||||||
|
投稿日時: 2007-09-03 18:13
そうだね。俺も↓の未記入の感じの悪さは理解できん。 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 ] | ||||||||||||||||||||||||
|
投稿日時: 2007-09-03 19:08
インターフェースや抽象クラスを、厳密に定義しなければならないのでしょうか。
C++ではインターフェースを定義出来ませんし、C#では複数のスーパー クラスを持てないところから、インターフェースを実装したスーパー クラスを作るなどの工夫をします。 言語仕様の制約の下、作りやすいもの、自己流定義に近いものを選ぶ、じゃダメですか? | ||||||||||||||||||||||||
|
投稿日時: 2007-09-03 20:51
うーん、未記入さんのおっしゃっていることと
他の方のおっしゃってることって本質的に何も変わらず、 言葉の言い換えにしか見えないのですが。
この場合なら、どちらもインタフェースで実装するでしょうね。 でも、ここにはそもそもis-aの対象となるクラスが書かれていないので当たり前のような気がします。 地上/飛行/小型/大型どれもインターフェースで、 ユニット(抽象クラスですね)を継承した具象クラスを挙げるなら、 戦車ユニット(地上、大型)、歩兵ユニット(地上、小型)みたいな感じですかね。 地上/飛行/小型/大型もあるオブジェクトの一部の性質でしかありません。 しかし、地上ユニット、飛行ユニット、小型ユニット、大型ユニットと 命名をしたことでユニットに対してそれぞれのクラスはis-aの関係になりました。 でも、この命名ならこれらはインタフェースではなく抽象クラスだと思いますよ。 各人の持つプログラミング言語のバックボーンが違うから、 設計時の命名の仕方が違うということなんだろうと勝手に推測しています。 |