C++/CLIをつつく27-インターフェイス。約束は守ろう。
じゃあ、早速インターフェイスの定義方をつつくピヨッ!
//実用的でない例
interface class IFoo
{
//実装するべきプロパティ
property Object^ FooProperty;
//実装するべきメソッド
void FooMethod( Object^ obj );
void FooMethod1( Object^ obj );
Object^ FooFunction( );
//実装するべきイベント
event EventHandler^ FooEvent;
};
どう?難しくないよね♪インターフェイスの定義はinterface classキーワードを使用するところと、Publicとかのアクセス修飾子は必ずpublicな点と、実装を書かない点がが特徴ピヨ。何故実装を書いたら駄目なのかというと、.NETではインターフェイスは実態がない契約(約束事)だからなんだよ。
この定義したインターフェイスを実装するクラスは次のようにするピヨ。
public ref class FooClass : IFoo
{
public:
virtual property Object^ FooProperty;
virtual void FooMethod( Object^ obj ) { }
virtual void FooMethod1( Object^ obj ){ }
virtual Object^ FooFunction( ){ return nullptr; }
virtual event EventHandler^ FooEvent;
};
C++/CLIではクラス名 : インタフェース名で指定して実装するんだ。VB.NETみたいに、一々各要素でどのインタフェース要素を実装するのかを宣言しなくてもいいピヨ。さらに、VB.NETと同じく複数に対応する事が不可能なんだ。その方法は後述するピヨ。その代りvirtualキーワードを必ずつけなくてはならないんだ。仕方ないよね。 話しは変わるけど、インターフェイスは複数指定できるからこんな状況に遭遇する場合があるピヨ
interface class IBar
{
//メソッド名がかぶっている!
void FooMethod1( Object^ obj );
};
//IBarのメソッドをどうしよう・・・
public ref class FooClass : IFoo, IBar
{
このように名前が偶然同じだった場合明示的実装という手法を使用するんだ。やり方は次の通りだピヨォ。
//明示的実装
virtual void FooMethod1( Object^ obj ) = IFoo::FooMethod1 { }
このように、メソッドの宣言の後に
=対応するインターフェイスの要素
を書けばいいんだちょっと違和感あるけど簡単だね。さらに、この機能を利用すればVB.NETと同じく一度に複数のインターフェイスが実装できるんだ。
virtual void FooMethod1( Object^ obj ) = IFoo::FooMethod1, IBar::FooMethod1 { }
こんな具合にピリオドで複数指定出来るんだ。これは便利。余り使いどころがないけどね・・・
最後に、インターフェイスとクラスの使い分けについて囀るピヨ。クラスは縦に継承されていくけど、インターフェースは横に継承される点が違うピヨ。 クラスの場合、親から子へと意味ある継承をするけど、全ての状況に対応できるわけじゃないんだ。 何故かというと、直接的には関係ないけど同じ要素を持つことがあるからなんだ。 クラスの継承は親子の遺伝。 インターフェイスの継承は師弟関係と覚えたらいいよ。
今回はこれで終わり。