インターフェース(Interface) にまつわる話。
インターフェースの基本
こういうインターフェースを作ると
publicinterfaeIFoo{stringGreet(stringto);}これは許されないが
publicclassFooImplementation:IFoo{stringGreet(stringto,inti){return"hello";}}これは許される。
publicclassFooTypeA:IFoo{stringGreet(stringto){return$"hello {to}";}}publicclassFooTypeB:IFoo{stringGreet(stringto){return$"こんにちは、{to}様";}}つまり "インターフェースで宣言したメソッドは実装クラスでその通りに実装されなければならない" という事。
良く知られた例としては IEnumerable<T> があり、いつも使う List&let;FooEntity> とかを foreach 出来るのも、string を foreach して1文字ずつ解析したりできるのも 実装クラスが必ずそう言う処理を実装しているから。
同じインターフェースに対する複数の実装
先の例の FooTypeA, FooTypeB は共に IFoo インターフェースを実装している。
これで何が嬉しいのかって言うのがイマイチ理解しづらいみたい。
サンプル
classProgram{publicstaticvoidMain(string[]args){IFoofoo=GetFoo(args[0]);if(foo!=null){Console.Write(foo.Greet("Mr. Boo");}}publicstaticIFooGetFoo(stringfooType){if(fooType"A")returnnewFooTypeA();elseif(fooType"B")returnnewFooTypeB();elsereturnnull;}}ここではコマンドライン引数で受け取ったタイプによって生成する実装クラス を切り替えて、メソッドGreet()を呼び出す。
void Mainを書く人はIFoo の実装クラスについてあまり詳細な事を知らなくても使える。
(ただし、自分の欲しい結果が何かは把握していないと困る)
つまり
- メソッドの形式が同じなので、インターフェースの定義を知っていれば使える
- 同じインターフェースを実装した複数のオブジェクトについて、同じメソッドを確実に呼び出すことができる(IDisposableなど = 常にusing{}できるとか)
- 何かの都合で処理内容を切り替えたい場合に使える
という事になる。
3番目の件、if や switch でどうにかすることもできるし、コンパイル定数で制御することもできるけども、テスト大変。