- - PR -
VB.NETのインターフェイスについて
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-02-20 12:31
あまりいい例ではないかもしれませんが、
というようなクラス群と継承関係があったとします。 ロボットや食虫植物や動物、及び、人、犬はすべて動くことができます。 継承関係にあるものもあれば、関係ないものもありますが、 「動ける」という点では同一視できてよいはずです。 では、動くことのできるクラスには、IMoveableインタフェースを実装するとしましょう。
例があまりよくないというのもありますが(^^;; IMoveable.Moveメソッドがどんな挙動をするのか?というデフォルトは 決めようがありませんし、ほとんどの場合、デフォルト実装なんて使い物にならないでしょう。 でも、このインタフェースによって、各クラスをある視点(この場合は動けるということ)から、 見た形でコーディングすることができます。 そのため、このインタフェースを引数に取るメソッドを実装するとき、 どんなクラスが渡されるか?は気にする必要がなく(気にしてはいけない)、 単純にMoveできるという機能を利用すればよいです。 基本クラスを継承したクラスを基本クラスの型で扱う場合と同じメリットを 直接は関係ないクラス同士でも得られるというのが大きいポイントだと思います。 [ メッセージ編集済み 編集者: よねKEN 編集日時 2004-02-20 12:34 ] | ||||||||||||
|
投稿日時: 2004-02-20 13:07
継承のメリットは、実装側からの観点よりも、呼び出し側からの観点の方がわかりやすいと思います。
よねKENさんの例で言えば『mv As IMoveable』の部分がポイントで、 つまり、IMovevaleインターフェイスが実装されているクラスはMoveメソッドを必ず呼出可能であることが保障されているわけです。 [ メッセージ編集済み 編集者: He 編集日時 2004-02-20 13:09 ] | ||||||||||||
|
投稿日時: 2004-02-20 13:17
.Netは全然使っていませんが、以前インターフェイスの有用性について理解してなかったもので^^;
自分の経験からすると、 「いきなり実装してしまえばインターフェイスなんて必要ないんじゃないか?」 というのがカウンターさんの疑問だと思うんですよ。 でも、大規模な開発などをしてると、それぞれの部品間の「インターフェイス」どのようなデータでプログラム間が繋がっているのか?というのを「表す」のにインターフェイスって便利だと思いませんか? (小規模だと、プログラムの見とおしがはっきりしているのでいきなり実装の方が早いと思いますが) ※以上、あまり理解しないまま書いてるので間違い等あったらフォローお願いします^^; | ||||||||||||
|
投稿日時: 2004-02-20 13:34
みなさん、貴重な意見をありがとうございます。
おかげで、なんとなくインターフェースのかけらが見えてきた感じです。
よねKENさんの例で言うと、「単純にMoveできるという機能」とは インターフェイスで定義されている「Sub Move()」の部分に当たるのでしょうか? それとも、「ある視点」というのが「Sub Move()」にあたるのでしょうか? はたまた、両方がそうなのでしょうか? もし、そうであれば、「視点」や「機能」というのはインターフェイスに 定義されている各要素から判断し、それにそぐわない内容を実装先で記述しないように するものなのでしょうか? | ||||||||||||
|
投稿日時: 2004-02-20 13:51
私もそのほうがわかりやすいと思います。>カウンターさんへ あるオブジェクトにメッセージを送る(メソッドを呼び出す)方法には 言語によっていろいろあります。 たとえば メッセージを表す値(オブジェクト)と引数オブジェクトを呼び出されるオブジェクト に渡せばよきにはからってくれる機構があります。 Javaや.NETでもリフレクション機能でこれを行えます。 (ソースがわかりにくくなるので、使う個所は限られてくると思います) この場合の切り口は、 ・あるメッセージに、呼び出し対象のオブジェクトが反応するかどうかしらべて 反応するなら呼び出す インターフェースの場合は、 ・あるメッセージ(の一群)に、呼び出し対象のオブジェクトが反応することを 保証するための簡便な機構 という感じでしょうか。
Moveというメッセージに反応するオブジェクトに Moveしなさい、というメッセージを送った場合、 送った側が期待する動作、というのがあると思いますので、 それにそった実装をしておくべきではないかと思います。 File.Write() というメッセージが実はファイル削除のメッセージである、 なんていうのは、おかしなインターフェースですよね | ||||||||||||
|
投稿日時: 2004-02-20 16:46
分析をしていると、様々なオブジェクトを「動かす」という操作が必要なことがわかりました。このとき、クラス1つ1つに「動かす」というメソッドを実装してもいいのですが、そうすると使う側はクラスの数だけ処理を書かなければなりません。 Select クラス case クラス1 キャスト(オブジェクト, クラス1).Move case クラス2 キャスト(オブジェクト, クラス1).Move ・・・ End Select これは非現実的です。クラスが増えれば、増えたぶんだけ場合を追加しなければなりません。 では、「基本クラス」を作ってそこに純粋仮想関数を作れば・・・とすると、本当に「基本クラス」は、「基本」なのでしょうか。関連のないクラスを1つのクラスから派生させるのは、オブジェクト指向の初期はあったようですが、最近では使用者を迷わせるもとになるのでやりません。 そこでインタフェースの出番です。インタフェースは「メソッド」だけが定義できます(プロパティも、フィールドに対するアクセスメソッドです)。クラス間の関連は「インタフェース」、何らかの共通の性質だけになります。コードも短くてすみます。 キャスト(オブジェクト, インタフェース).Move インタフェースがあって、それにあわせて実装するのではありません。要求があって、それにあうインタフェースを作り、インタフェースを実装する必要があるから実装します。 #「動かす」という他動詞と、「動く」という自動詞では、ちょっと違うよなぁ・・・ | ||||||||||||
|
投稿日時: 2004-02-20 17:12
Jittaさんありがとうございます。
一つ一つのクラスにメソッドを実装するのは非現実的なので、 インターフェイスの出番だということはなんとなくわかるんですが、
たしかに、インターフェイスでメソッドを定義して必要なクラスで実装すれば 良いような気はするんですが、インターフェイスはあくまでもテンプレートですよね? ということは、実装先でメソッドの内容を記述する必要があると理解しています。 そうすると、結局は一つ一つのクラスにメソッドを実装することになるのではと 考えてしまいます。 | ||||||||||||
|
投稿日時: 2004-02-20 18:11
インターフェイスはメソッド実装の記述量を少なくするためのものではありません。 # クラスの継承は半分この目的で行う場合もありますが。 Jittaさんが仰っている「コードも短くてすむ」というのは、呼び出されるメソッドの実装に関してではありません。呼び出す側のコードです。 ただ、この辺は、複数の実装を抽象的に呼び出せることのメリットの実例がないと分かってもらいにくいかもしれませんが。 重要なのは呼び出し側(使う側)にどうやって柔軟性のある機能を提供するかです。 Encoding とか Stream、Collectionなんかはメリットが分かりやすいかも知れません。 StreamやEncodingはクラス継承ですが、インターフェイスと同じメリットのために使用している部分があります(プラス、基本の実装となる部分が多いためクラスにしているという感じ)。 Collection系はインターフェイスを多用していますね。 実装の継承が多い場合は、抽象クラスにした方が便利なこともありますが、実装に共通点がない場合はインターフェイスにするべきです。 まあ、実装に共通点が多くても、さらに一段階上にインターフェイスをもってきたりもしますが。 インターフェイスにすることで、逆に他のクラス実装を継承できる可能性があります(こちらは実装の継承目的)。 っていうか、根本的なところで、多態とかポリモーフィズムという概念は理解されてますか?ここを理解していないと、意図が伝わらないと思います。 |