- PR -

VB.NETのインターフェイスについて

投稿者投稿内容
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2004-02-20 12:31
引用:

カウンターさんの書き込み (2004-02-20 11:44) より:
結局インターフェイスを実装するということは、各クラスでインターフェイスで定義された
名前を使いまわすということなのでしょうか?

(snip)

ん〜、継承のように中身があるものを使いまわすなら、その意義も感じられるのですが。
インターフェイスのように実装先で処理内容を変更できる場合の有効性がいまいちです。
なんだか混乱してきました。



あまりいい例ではないかもしれませんが、
コード:

? ?
| |
NO生物 生物---------+
| | |
ロボット 植物 動物------+
(動く) | (動く) |
| | |
食虫植物 人 犬
(動く) (動く) (動く)



というようなクラス群と継承関係があったとします。
ロボットや食虫植物や動物、及び、人、犬はすべて動くことができます。
継承関係にあるものもあれば、関係ないものもありますが、
「動ける」という点では同一視できてよいはずです。

では、動くことのできるクラスには、IMoveableインタフェースを実装するとしましょう。
コード:

' インタフェースの定義
Interface IMovevale()
Sub Move()
End Interface

' インタフェースの利用の例
' mvArray にはIMoveableを実装したインスタンスの配列とします。
' ロボット、食虫植物、人間、犬 etc
For Each mv As IMoveable In mvArray
mv.Move() ' なんか知らんけど、よく動きます
Next



例があまりよくないというのもありますが(^^;;
IMoveable.Moveメソッドがどんな挙動をするのか?というデフォルトは
決めようがありませんし、ほとんどの場合、デフォルト実装なんて使い物にならないでしょう。

でも、このインタフェースによって、各クラスをある視点(この場合は動けるということ)から、
見た形でコーディングすることができます。

そのため、このインタフェースを引数に取るメソッドを実装するとき、
どんなクラスが渡されるか?は気にする必要がなく(気にしてはいけない)、
単純にMoveできるという機能を利用すればよいです。

基本クラスを継承したクラスを基本クラスの型で扱う場合と同じメリットを
直接は関係ないクラス同士でも得られるというのが大きいポイントだと思います。


[ メッセージ編集済み 編集者: よねKEN 編集日時 2004-02-20 12:34 ]
He
大ベテラン
会議室デビュー日: 2002/12/18
投稿数: 141
投稿日時: 2004-02-20 13:07
継承のメリットは、実装側からの観点よりも、呼び出し側からの観点の方がわかりやすいと思います。
よねKENさんの例で言えば『mv As IMoveable』の部分がポイントで、
つまり、IMovevaleインターフェイスが実装されているクラスはMoveメソッドを必ず呼出可能であることが保障されているわけです。

[ メッセージ編集済み 編集者: He 編集日時 2004-02-20 13:09 ]
冬寂
ぬし
会議室デビュー日: 2002/09/17
投稿数: 449
投稿日時: 2004-02-20 13:17
.Netは全然使っていませんが、以前インターフェイスの有用性について理解してなかったもので^^;

自分の経験からすると、
「いきなり実装してしまえばインターフェイスなんて必要ないんじゃないか?」
というのがカウンターさんの疑問だと思うんですよ。

でも、大規模な開発などをしてると、それぞれの部品間の「インターフェイス」どのようなデータでプログラム間が繋がっているのか?というのを「表す」のにインターフェイスって便利だと思いませんか?
(小規模だと、プログラムの見とおしがはっきりしているのでいきなり実装の方が早いと思いますが)

※以上、あまり理解しないまま書いてるので間違い等あったらフォローお願いします^^;
カウンター
大ベテラン
会議室デビュー日: 2004/02/19
投稿数: 123
投稿日時: 2004-02-20 13:34
みなさん、貴重な意見をありがとうございます。
おかげで、なんとなくインターフェースのかけらが見えてきた感じです。

引用:

でも、このインタフェースによって、各クラスをある視点(この場合は動けるということ)から、
見た形でコーディングすることができます。

そのため、このインタフェースを引数に取るメソッドを実装するとき、
どんなクラスが渡されるか?は気にする必要がなく(気にしてはいけない)、
単純にMoveできるという機能を利用すればよいです。



よねKENさんの例で言うと、「単純にMoveできるという機能」とは
インターフェイスで定義されている「Sub Move()」の部分に当たるのでしょうか?
それとも、「ある視点」というのが「Sub Move()」にあたるのでしょうか?
はたまた、両方がそうなのでしょうか?
もし、そうであれば、「視点」や「機能」というのはインターフェイスに
定義されている各要素から判断し、それにそぐわない内容を実装先で記述しないように
するものなのでしょうか?


ナキヲ
常連さん
会議室デビュー日: 2003/08/22
投稿数: 32
お住まい・勤務地: 京都・自宅から勤務地まで自転車で40分
投稿日時: 2004-02-20 13:51
引用:
継承のメリットは、実装側からの観点よりも、呼び出し側からの観点の方がわかりやすいと思います。



私もそのほうがわかりやすいと思います。>カウンターさんへ

あるオブジェクトにメッセージを送る(メソッドを呼び出す)方法には
言語によっていろいろあります。
たとえば
メッセージを表す値(オブジェクト)と引数オブジェクトを呼び出されるオブジェクト
に渡せばよきにはからってくれる機構があります。
Javaや.NETでもリフレクション機能でこれを行えます。
(ソースがわかりにくくなるので、使う個所は限られてくると思います)

この場合の切り口は、
・あるメッセージに、呼び出し対象のオブジェクトが反応するかどうかしらべて
 反応するなら呼び出す

インターフェースの場合は、
・あるメッセージ(の一群)に、呼び出し対象のオブジェクトが反応することを
 保証するための簡便な機構

という感じでしょうか。

引用:
定義されている各要素から判断し、それにそぐわない内容を実装先で記述しないように


Moveというメッセージに反応するオブジェクトに
Moveしなさい、というメッセージを送った場合、
送った側が期待する動作、というのがあると思いますので、
それにそった実装をしておくべきではないかと思います。
File.Write() というメッセージが実はファイル削除のメッセージである、
なんていうのは、おかしなインターフェースですよね

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-20 16:46
引用:

カウンターさんの書き込み (2004-02-20 13:34) より:

よねKENさんの例で言うと、「単純にMoveできるという機能」とは
インターフェイスで定義されている「Sub Move()」の部分に当たるのでしょうか?
それとも、「ある視点」というのが「Sub Move()」にあたるのでしょうか?
はたまた、両方がそうなのでしょうか?
もし、そうであれば、「視点」や「機能」というのはインターフェイスに
定義されている各要素から判断し、それにそぐわない内容を実装先で記述しないように
するものなのでしょうか?


 分析をしていると、様々なオブジェクトを「動かす」という操作が必要なことがわかりました。このとき、クラス1つ1つに「動かす」というメソッドを実装してもいいのですが、そうすると使う側はクラスの数だけ処理を書かなければなりません。

Select クラス
 case クラス1
  キャスト(オブジェクト, クラス1).Move
 case クラス2
  キャスト(オブジェクト, クラス1).Move
・・・
End Select

これは非現実的です。クラスが増えれば、増えたぶんだけ場合を追加しなければなりません。

 では、「基本クラス」を作ってそこに純粋仮想関数を作れば・・・とすると、本当に「基本クラス」は、「基本」なのでしょうか。関連のないクラスを1つのクラスから派生させるのは、オブジェクト指向の初期はあったようですが、最近では使用者を迷わせるもとになるのでやりません。

 そこでインタフェースの出番です。インタフェースは「メソッド」だけが定義できます(プロパティも、フィールドに対するアクセスメソッドです)。クラス間の関連は「インタフェース」、何らかの共通の性質だけになります。コードも短くてすみます。

キャスト(オブジェクト, インタフェース).Move


 インタフェースがあって、それにあわせて実装するのではありません。要求があって、それにあうインタフェースを作り、インタフェースを実装する必要があるから実装します。


#「動かす」という他動詞と、「動く」という自動詞では、ちょっと違うよなぁ・・・
カウンター
大ベテラン
会議室デビュー日: 2004/02/19
投稿数: 123
投稿日時: 2004-02-20 17:12
Jittaさんありがとうございます。
一つ一つのクラスにメソッドを実装するのは非現実的なので、
インターフェイスの出番だということはなんとなくわかるんですが、

引用:

Jittaさんの書き込み (2004-02-20 16:46) より:
 そこでインタフェースの出番です。インタフェースは「メソッド」だけが定義できます(プロパティも、フィールドに対するアクセスメソッドです)。クラス間の関連は「インタフェース」、何らかの共通の性質だけになります。コードも短くてすみます。



たしかに、インターフェイスでメソッドを定義して必要なクラスで実装すれば
良いような気はするんですが、インターフェイスはあくまでもテンプレートですよね?
ということは、実装先でメソッドの内容を記述する必要があると理解しています。
そうすると、結局は一つ一つのクラスにメソッドを実装することになるのではと
考えてしまいます。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-02-20 18:11
引用:

カウンターさんの書き込み (2004-02-20 17:12) より:
たしかに、インターフェイスでメソッドを定義して必要なクラスで実装すれば
良いような気はするんですが、インターフェイスはあくまでもテンプレートですよね?
ということは、実装先でメソッドの内容を記述する必要があると理解しています。
そうすると、結局は一つ一つのクラスにメソッドを実装することになるのではと
考えてしまいます。


インターフェイスはメソッド実装の記述量を少なくするためのものではありません。
# クラスの継承は半分この目的で行う場合もありますが。

Jittaさんが仰っている「コードも短くてすむ」というのは、呼び出されるメソッドの実装に関してではありません。呼び出す側のコードです。
ただ、この辺は、複数の実装を抽象的に呼び出せることのメリットの実例がないと分かってもらいにくいかもしれませんが。

重要なのは呼び出し側(使う側)にどうやって柔軟性のある機能を提供するかです。

Encoding とか Stream、Collectionなんかはメリットが分かりやすいかも知れません。
StreamやEncodingはクラス継承ですが、インターフェイスと同じメリットのために使用している部分があります(プラス、基本の実装となる部分が多いためクラスにしているという感じ)。
Collection系はインターフェイスを多用していますね。

実装の継承が多い場合は、抽象クラスにした方が便利なこともありますが、実装に共通点がない場合はインターフェイスにするべきです。
まあ、実装に共通点が多くても、さらに一段階上にインターフェイスをもってきたりもしますが。
インターフェイスにすることで、逆に他のクラス実装を継承できる可能性があります(こちらは実装の継承目的)。

っていうか、根本的なところで、多態とかポリモーフィズムという概念は理解されてますか?ここを理解していないと、意図が伝わらないと思います。

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