※以下個人的な覚書です。
情報の正当性や、妥当性は保障しかねます。
普段Interfaceと聞くと、ついついJavaで見かけるようなInterfaceを想像します。
もちろん.NETにもJavaのような使用方法もありますが、
この記事では、インターフェースを型として宣言したり、メソッドの引数にするような使用方法を個人的にまとめます。
[開発環境]:Visual Stdio.NET 2003
[開発言語]:Visual Basic.NET(VB.NET)
[実行環境]:Windows Xp SP2
□Javaのinterfaceと同等のコード
‘Subプロシージャとプロパティを持つインターフェース
Public Interface IMyIF1
Property Msg() As String
Sub ShowMsg()
End Interface
※VB.NETではインターフェースに宣言できるのは、Sub,Functionおよびプロパティのみ。
‘IMyIFを実装した、IFTestクラス
Public Class IFTest
Implements IMyIF1
Private strMsg As String
Public Property Msg() As String Implements IMyIF1.Msg
Get
Return strMsg
End Get
Set(ByVal Value As String)
Me.strMsg = Value
End Set
End Property
Public Sub ShowMsg() Implements IMyIF1.ShowMsg
MsgBox(strMsg)
End Sub
End Class
ここまでのコードを見ると、言語の違いのみでJavaと等価といえます。
ただし、VB.NETに限って言うと、それぞれのプロシージャ、プロパティの
宣言の後に”Implements~”が書かれています。
これにより、実装するクラス側ではInterfaceで宣言したものと異なった名前
をつけることが可能です。
すでにご存知の方もいらっしゃると思いますが、
IDEが優秀なおかげ(?)で、Implements IMyIF1を記述した時点で、
実装コードは自動的に生成されます。
今回は僕が書き加えたのは、
・strMsgの宣言
・プロパティのGet,Setの中身。
・ShowMsgプロシージャの内容
のみです。
□インターフェースを型として宣言する。
まず、通常通りにIFTestクラスのインスタンスを生成してみます。
‘IFTestクラスのインスタンス生成
Dim IFTestObj As New IFTest
当然ながら、プロパティ「Msg」,プロシージャ「ShowMsg」を使用することができます。
次に何も考えずにIMyIF1を型として宣言してみましょう。
‘Interfaceの宣言
Dim IMyIF1Obj As IMyIF1
※InterfaceはNewすることは出来ません。
‘すると以下のように見事Interfaceのプロパティや、プロシージャにアクセスできます。
IMyIF1Obj.Msg = “test”
IMyIF1Obj.ShowMsg()
が、実行すると「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
というエラーが出ます。
.NET触り始によく出したエラーですね(笑)
ここからが本題です。
上記コードでは、Interfaceのみを宣言した形になります。
ここで魔法の1行。
Dim IFTestObj As New IFTest
Dim IMyIF1Obj As IMyIF1
IMyIF1Obj = IFTestObj
IMyIF1Obj.Msg = “test”
IMyIF1Obj.ShowMsg()
あら不思議。
見事”test”とメッセージボックスが表示されましたね。
ここで僕の大好きな@ITから引用させてもらうと
@IT:連載 オブジェクト指向プログラミング超入門 最終回 オブジェクトをつなぐためのインターフェイス
インターフェイスを実装しているクラスは、そのインターフェイスの型の変数にキャストなしで代入することができます。
ふむふむ。
ここで@ITを呼んで理解できた人はすごい。
正直僕はいまだに理解してません(^^;;
本当にInterfaceを実装していればキャストせずに代入できるのか!?
ためしにもう一つInterfaceを作ってみます。
‘IFTestクラスに新たにShowMsg2を実装させるためのInterface
Public Interface IMyIF2
Sub ShowMsg2()
End Interface
実際にIFTestクラスに実装しましょう。
Public Class IFTest
Implements IMyIF1, IMyIF2
Private strMsg As String
Public Property Msg() As String Implements IMyIF1.Msg
Get
Return strMsg
End Get
Set(ByVal Value As String)
Me.strMsg = Value
End Set
End Property
Public Sub ShowMsg() Implements IMyIF1.ShowMsg
MsgBox(strMsg)
End Sub
Public Sub ShowMsg2() Implements IMyIF2.ShowMsg2
MsgBox(“ShowMsg2:” & strMsg)
End Sub
End Class
結局こんな感じになりました。
それではここから実験。
Dim IFTestObj As New IFTest
Dim IMyIF1Obj As IMyIF1
Dim IMyIF2Obj As IMyIF2
‘IMyIF1
IMyIF1Obj = IFTestObj
IMyIF1Obj.Msg = “test”
IMyIF1Obj.ShowMsg()
‘IMyIF1
IMyIF2Obj = IFTestObj
IMyIF2Obj.ShowMsg2()
どうでしょうか。
なんとなくわかっていただけたでしょうか?
正直本人すらよく分かってないものを一生懸命説明しても仕方ないんですが。。。
説明を書いている過程でひらめくかなと思った次第だったのですが、
あまりひらめきませんでしたorz
とりあえず、個人的なまとめとして、
・Javaのように使うことが出来る。
・Interfaceを実装しているクラスは、実装済みのInterfaceに代入できる。
・代入後、型として指定したInterfaceのメソッドや、プロパティを利用できる。
といったところでしょうか。
良いサンプルでなくて申しわけないのですが。
補足させていただくと、最近MSHTMLをよく触っていまして、
そこにIHTMLDocument,IHTMLDocument2,IHTMLDocument3,IHTMLDocument4,
IHTMLElement,IHTMLElement2などといったたくさんのインターフェースが
あったわけです。
この場合IHTMLDocument系のインターフェースはすべてHTMLDocumentClassというクラスが実装しています。(親クラスとでも言うんでしょうか)
それで何気なく、bodyにアクセスしたいときはIHTMLDocumentをつかうとか、
writeメソッドやwritelnメソッドを使いたいときはIHTMLElement2を使うなど、
適当にいじっていたわけです。
それで、どうも.NETというか、COM(?)のインターフェースは何か違うと感じ、
この記事にいたったわけです。
※もちろん、MSHTMLは8Mほどのファイルを再配布する必要があるので、
TypeクラスやとType.InvokeMembeなど駆使して利用していますが。。。
そのうちMSHTMLを使ったDOMHTMLでのHTML解析のサンプルも載せたいと思います。
最後に・・・
もしこの記事を読まれた方で、誤りを見つけられた方や、ご指摘のある方は、コメントの方へお願いしますm(_ _”m)ペコリ
まだまだ僕も勉強が足りてないなぁと思う今日この頃でした。
ではでは。またの機会に。