Cのインターフェイス#

C#を習い始めたばかりの人にとって、インターフェースとは何か、なぜ必要なのかという疑問がしばしば生じます。



まず、検索エンジンの最初のリンクで見つけることができるものについて。 ほとんどの記事では、インターフェイスの意味は、クラスに含める必要があるもの、プロパティとメソッドに関する「契約」として説明されています。 たとえば、インターフェイスがあります。



public interface IForecast { int GetForecast(int value); int Size { get; set; } }
      
      







したがって、一部のクラスがこのインターフェイスを実装する場合、int GetForecast(int value)メソッドとSizeプロパティの実装を含める必要があります。



そのような合意の実際的な価値は最小限です。 インターフェイスをプロジェクトから外すと、すべてがインターフェイスなしで正常に機能します。 クラスのロジックを完全に書き直したいのでなければ、インターフェースは必要なメソッドを忘れないようにするのに役立ちます。



この部分を要約すると、インターフェイスが1つのクラスのみに実装されている場合、時間を無駄にしないでください。 彼はただ必要ではありません。







追加

出版直後、批判の海が私に降り注ぎました。最初は答えようとしましたが、それが意味をなさないことに気づきました。 すべての批評家は、前の段落で書いたものに依存し、多くのクラス、あらゆる種類のリンク、チームサポートなどがあるプロジェクトの複雑な例を挙げようとします。 エントリーを簡単に要約したのはおそらく間違いだった。 しかし、肝心なのは、インターフェイスが常に必要なわけではないということです。 スケーリングを計画していない個人的な(またはあまり大きくない)プロジェクトがあり、誰も言及しておらず、最も重要なことですが、それが正常に機能する場合、プロジェクトにインターフェイスを導入しても何も変わりません。 そして、誰かがかつてインターフェースを実装して不滅になったという物語を発明しないでください。 どこでもインターフェイスが必要な場合、それはクラスの不可欠な部分になります。



この記事では、プロジェクト間の接続ではなく、1つのプロジェクト内でのインターフェースの使用方法について説明します。 これについてはまだ批判がありません。



追加終了



幸いなことに、インターフェースの機能ははるかに興味深いものです。 インターフェイスは、異種オブジェクトに共通の機能を設定できます。これにより、コードの柔軟性の面で非常に大きな機会が開かれます。



たとえば、2つのクラスがあるとします。



 class First
      
      



そして
 class Second
      
      







これらは完全に異なる2つのクラスですが、共通点を持たせてください。 ロジックを追加せずに、1つのメソッドを両方で機能させたいのです。 この場合、共通のインターフェースを実装できます。 これらのクラスを



 class First : IForecast
      
      



そして
 class Second : IForecast
      
      







これで、それらの一般的なメソッドを作成できます。



 void AnyMethod(IForecast anyClass) { var value = anyClass.GetForecast(10); }
      
      







ご覧のとおり、値変数は、型変換アクションなどを追加せずにパラメーターとして渡されるクラスからGetForecast関数の値を受け取ります。



別の例では、計算中にどのクラスが必要になるかを事前に知りませんが、作業を開始する前にこのクラスのインスタンスを宣言する必要があります。 この場合、インターフェイスを実装するクラスのインスタンスを宣言できます。



 ... IForecast any; …  : if(...) any = new First(); else any = new Second();
      
      







さらに進んで、そのようなオブジェクトの配列(またはリスト)を宣言できます。



 var array = new IForecast[2]; array[0] = new First(); array[1] = new Second();
      
      







そして、たとえば、すべてのSizeプロパティの合計を計算できます。



 var summ = 0; foreach (var forecast in array) { summ += forecast.Size; }
      
      







インターフェースを介した広告には1つの欠点があります。インターフェースとクラス自体で宣言されたメソッドとプロパティのみが使用可能です。 クラスがベースから継承されている場合、そのメソッドにアクセスするには、型キャストを行う必要があります。



 public class BaseClass { public int GetValue(int value) { return value * 2; } } public class Second: BaseClass, IForecast IForecast frc; frc = new Second(); var frcBase = (BaseClass) frc; var result = frcBase.GetValue(45);
      
      







インターフェイスのもう1つの焦点は、同じクラスの2つのインターフェイスを署名の同じメソッドで実装する機会を使用して行うことができますが、コンテンツは異なります。 既に述べた以外の実際的な利点がわからないが、突然関数の名前を思い付く想像力がなければ、それらをインターフェースに入れることができる。



たとえば、プロジェクトに別のインターフェイスを追加します。



 public interface IForecast2 { int GetForecast(int value); }
      
      







そして、両方のインターフェースを継承する新しいクラスを作成します。



 public class Third: IForecast, IForecast2 { int IForecast.GetForecast(int value) { return value + Size; } public int Size { get; set; } int IForecast2.GetForecast(int value) { return 2 * value + Size; } }
      
      







これは、明示的なインターフェイス実装と呼ばれます。 これで、この設計を構築できます。



  var third = new Third {Size = 10}; var v1 = ((IForecast) third).GetForecast(100); var v2 = ((IForecast2)third).GetForecast(100); Console.WriteLine(v1+v2);
      
      







興味深いことに、このようなインターフェイスを実装する場合、アクセス修飾子(「パブリック」など)をメソッドに割り当てることはできませんが、型キャストを通じてパブリックとしてアクセスできます。



ご覧のとおり、これは機能しますが、見た目が大きすぎます。 どういうわけかコードを改善するために、少し異なる方法で書くことができます:



 var third = new Third {Size = 10}; var bad = (IForecast) third; var good = (IForecast2) third; var v1 = bad.GetForecast(100); var v2 = good.GetForecast(100); Console.WriteLine(v1+v2)
      
      



;



badとgoodは3番目を指しますが、異なるインターフェイスに留意してください。 ゴーストを1回実行すると、その結果を繰り返し使用できます。 場合によっては、これによりコードが読みやすくなる可能性があります。



インターフェイスの別のアプリケーションは、関数のスタブの迅速な製造です。

たとえば、チームで大規模なプロジェクトを構築しており、クラスは同僚が書いたクラスに依存しています。 しかし、まだ書かれていません。 賢いボスは、プロジェクト開発の最初の段階ですべての主要なクラスのインターフェイスを準備しました。同僚を待たずに、クラスにスタブクラスを実装できます。 すなわち 一時クラスにはロジックは含まれませんが、動作するふりをするだけです。呼び出しを行い、適切な値を返します。 これを行うには、同僚が受け取ったのと同じインターフェースを実装するだけです。



この記事のすべての例を含む作業プロジェクトは、次のリンクから参照できます: リンク



All Articles