- PR -

インタフェースと抽象クラスの混合は問題ない?

投稿者投稿内容
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2006-06-09 09:07
私も lalupin4 さんのように、
抽象クラス自体に実際に基底とするインターフェースを定義しておいて、
汎用ロジック内で"アルゴリズム"を使用する箇所では、
抽象クラスとしてインターフェースとして扱うことが多いです。
こうすれば、抽象クラスから派生したものではない別の"アルゴリズム"も扱えます。

抽象クラスでほとんどのことが実装できて派生クラスでは+α程度であればいいのですが、
原型がないほどにオーバーライドしなくてはいけなくなる場合には、
インターフェースを実装した全く別のクラスを作ったほうがすっきりすることもあります。


[ メッセージ編集済み 編集者: masa 編集日時 2006-06-09 09:12 ]
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-06-09 09:16
引用:

masaさんの書き込み (2006-06-09 09:07) より:
原型がないほどにオーバーライドしなくてはいけなくなる場合には、
インターフェースを実装した全く別のクラスを作ったほうがすっきりすることもあります。


このあたりはJava寄りな思考に思えるが・・・
そんなことは起きちゃいけないし。この場合は設計を見直すべき。
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2006-06-09 09:33
書き方がまずかったかもしれませんね。
もちろん「何でもあり」な状態は好ましくないと思います。

やりたいことが整理されてそれがインターフェースとして定義された上で、
大半は同じような実装で対応できるので
ベースとして使用するための抽象クラスを用意している。
そして各プログラマには抽象クラスを使うように指示。

という状況を想定しています。
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2006-06-09 22:36
 お、ちょっと盛り上がってきてうれしい。

引用:

囚人さんの書き込み (2006-06-08 12:42) より:
何と言うか、「抽象に依存せよ」とかそんな感じの意味です。


引用:

unibonさんの書き込み (2006-06-08 12:54) より:実践的な(ダーティーな)用途を考えると、interface のほうがいじりやすくて適していることもあります。


 前者が主、後者が従。よってさしあたり前者についてだけ述べます。

 「抽象に依存せよ」という命題が是なら、
「抽象なabstract(実装を含み得る)」と「より抽象なinterface(実装を含み得ない)」とで
後者が優位なのは自明であり:
引用:

がらすさんの書き込み (2006-06-08 10:48) より:
出来る限りインタフェースを使った方が良い


というのがより自然な帰結です。
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2006-06-09 22:50
引用:
Elleさんの書き込み (2006-06-09 08:59) より:
コード例としてはlalupin4さんと同じ意見です。
(ファクトリを作るかどうかはわかりませんが。)

 わーい。Factoryは即興で書いたので横着しました。
実際にはGet(Createにすればよかった…)の引数は
アルゴリズム選択の条件を渡すことになるでしょう
(ちなみにstaticではなくSingletonパターンで書くでしょう)。

引用:
Javaの標準ライブラリは、APIとしてそのように提供しているものがあります。

 .NETだってそうだよ〜。
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2006-06-09 22:54
引用:

masaさんの書き込み (2006-06-09 09:07) より:
抽象クラスでほとんどのことが実装できて派生クラスでは+α程度であればいいのですが、
原型がないほどにオーバーライドしなくてはいけなくなる場合には、
インターフェースを実装した全く別のクラスを作ったほうがすっきりすることもあります。

 稀に(設計がそれなりに適切でも)ありますね。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-06-09 23:43
引用:

 お、ちょっと盛り上がってきてうれしい。


では、更に盛り上げ。

そもそも大事な事が抜けていましたね。
引用:

出来る限りインタフェースを使った方が良い


出来る限り「何より」インタフェースを使った方が良いのか。
これが食い違っていたら話が噛み合わないでしょう。

がらすさんは、abstract class と interface の例を出して、「インターフェースを使った方が良い」と仰っているので、「出来る限り abstract より interface を使った方が良い」
という意味で仰っています。(多分)

私は一般的に言われているそれは「出来る限り具体的なクラスよりインターフェース(抽象)を使った方が良い」という意味ですよ、と言っています。
ここで言う「インターフェース」とは interface の事ではありません。

本当に「抽象クラス(abstract)よりインターフェース(interface)を使った方が良い」と世間では言われているでしょうか?これらは目的、意味が違うと思いますが。

引用:

 前者が主、後者が従。よってさしあたり前者についてだけ述べます。

 「抽象に依存せよ」という命題が是なら、
「抽象なabstract(実装を含み得る)」と「より抽象なinterface(実装を含み得ない)」とで
後者が優位なのは自明であり:
引用:
引用:

がらすさんの書き込み (2006-06-08 10:48) より:
出来る限りインタフェースを使った方が良い


というのがより自然な帰結です。

逆に「実装を含み得たら」より抽象でないのは自明という事でしょうか?

コード:
interface IInter
{
	void Func();
}

abstract Abst
{
	public abstract void Func();
	protected virtual void Hoge()
	{
		…
	}
}


どちらがより抽象でしょうか?IInter や Abst のクライアントからは、どちらも Func() という抽象(インターフェース)を持った抽象概念です。抽象度は同一だと思います。

では、IInter や Abst を実装または派生するクラスから見た場合はどうでしょうか。
IInter の方が抽象度が高いかもしれませんが、そもそも「継承」は結合度が最も高い概念です。という事は継承関係にあるものは抽象などそもそもないので考える必要はありません。

_________________
囚人のジレンマな日々
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-06-10 08:58
引用:

囚人さんの書き込み (2006-06-09 23:43) より:

そもそも大事な事が抜けていましたね。
引用:

出来る限りインタフェースを使った方が良い


出来る限り「何より」インタフェースを使った方が良いのか。
これが食い違っていたら話が噛み合わないでしょう。


手元にある「C#コーディング標準(C)河端善博氏」という例のブツによると、P13の(39)に次のように書いてありました(^^;

-------------/ 引用開始 /-------------------
抽象クラス(abstract Class)はなるべく使わず、interface を多用せよ。abstract Classは、一部実装があり、一部抽象メソッドであるような場合にのみ使う。

理由:interface は幾つでも継承できるが、Classは1つだけ。1つから継承してしまうと、もう継承できずもったいない。
-------------/ 引用終了 /-------------------

ここから来ているのかな〜?と勝手に推測してみる・・・

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