English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
人間の世界では、2人以上の人々の間の契約は、契約に従うことを約束します。同様に、インターフェースには関連する機能の宣言が含まれています。インターフェースを実装する実体は、宣言された機能の実装を提供する必要があります。
C# では、interface キーワードを使用してインターフェースを定義できます。インターフェースには、メソッド、プロパティ、インデクサーやイベントの宣言が含まれますが、フィールドや自動実装のプロパティは含まれません。
以下のインターフェースはファイル操作の基本的な機能を宣言しています。
interface IFile { void ReadFile(); void WriteFile(string text); }
アクセス修飾子はインターフェースメンバーに適用できません。デフォルトでは、すべてのメンバーがパブリックです。インターフェースでアクセス修飾子を使用すると、C# コンパイラは「修飾子 'public'」というコンパイル時エラーを出力します。/private/protected' はこのアイテムに対して有効ではありません。(Visual Studio は即座にエラーを表示し、コンパイルを行いません。)
interface IFile { protected void ReadFile(); //コンパイル時エラー private void WriteFile(string text);//コンパイル時エラー }
インターフェースは宣言のみを含むことができ、実装を含むことはできません。以下はコンパイル時エラーを引き起こします。
interface IFile { void ReadFile(); void WriteFile(string text){ Console.Write(text); //エラー:メソッドの実装ができません } }
クラスまたはStructは、コロン(:)を使用して1つまたは複数のインターフェースを実装できます。
構文:
<Class or Struct Name> : <Interface Name>
例えば、以下のクラスはIFileインターフェースを暗黙的に実装しています。
interface IFile { void ReadFile(); void WriteFile(string text); } class FileInfo : IFile { public void ReadFile() { Console.WriteLine("Reading File") } public void WriteFile(string text) { Console.WriteLine("ファイルに書き込み中"); } }
上記の例では、FileInfoクラスがIFileインターフェースを実装しています。それによりpublicアクセス修飾子でIFileインターフェースのすべてのメンバーを定義しています。FileInfoクラスはインターフェースメンバー以外のメンバーも含むことができます。
インターフェースメンバーはpublic修飾子で実装する必要があります;そうしないとコンパイラがコンパイル時エラーを出します。
以下のように、このクラスのオブジェクトを作成し、インターフェースの変数に割り当てることができます。
public class Program { public static void Main() { IFile file1 = new FileInfo(); FileInfo file2 = new FileInfo(); file1.ReadFile(); file1.WriteFile("content"); file2.ReadFile(); file2.WriteFile("content"); } }
上記では、FileInfoクラスのオブジェクトを作成し、それをIFile型の変数とFileInfo型の変数に割り当てました。インターフェースが暗黙的に実装されている場合、IFile型の変数およびFileInfo型の変数を使用してIFileメンバーにアクセスできます。
インターフェースは<InterfaceName>.<MemberName>を使用して明示的に実装できます。クラスが複数のインターフェースを実装している場合、明示的な実装は便利です;したがって、読みやすく混乱を避けることができます。インターフェースに同じメソッド名がある場合も便利です。
以下を public 修飾子は明示的な実装と一緒に使用されます。それによりコンパイル時エラーが発生します。
interface IFile { void ReadFile(); void WriteFile(string text); } class FileInfo : IFile { void IFile.ReadFile() { Console.WriteLine("Reading File") } void IFile.WriteFile(string text) { Console.WriteLine("ファイルに書き込み中"); } }
インターフェースを実装する際には、インターフェースのインスタンスのみを通じてインターフェースのメンバーにアクセスできます。
interface IFile { void ReadFile(); void WriteFile(string text); } class FileInfo : IFile { void IFile.ReadFile() { Console.WriteLine("Reading File") } void IFile.WriteFile(string text) { Console.WriteLine("ファイルに書き込み中"); } public void Search(string text) { Console.WriteLine("ファイル内で検索中"); } } public class Program { public static void Main() { IFile file1 = new FileInfo(); FileInfo file2 = new FileInfo(); file1.ReadFile(); file1.WriteFile("content"); //file1.Search("検索するテキスト")//コンパイル時エラー file2.Search("検索するテキスト"); //file2.ReadFile(); //コンパイル時エラー //file2.WriteFile("content"); //コンパイル時エラー } }
上記の例では、file1オブジェクトがアクセスできるメンバーIFile、およびfile2FileInfoクラスのメンバーにアクセスできます。これは明示的な実装の限界です。
クラスや構造体は複数のインターフェースを実装できます。すべてのインターフェースのすべてのメンバーを実装する必要があります。
interface IFile { void ReadFile(); } interface IBinaryFile { void OpenBinaryFile(); void ReadFile(); } class FileInfo : IFile, IBinaryFile { void IFile.ReadFile() { Console.WriteLine("テキストファイルを読み取り中"); } void IBinaryFile.OpenBinaryFile() { Console.WriteLine("バイナリファイルをオープン中"); } void IBinaryFile.ReadFile() { Console.WriteLine("バイナリファイルを読み取り中"); } public void Search(string text) { Console.WriteLine("ファイル内で検索中"); } } public class Program { public static void Main() { IFile file1 = new FileInfo(); IBinaryFile file2 = new FileInfo(); FileInfo file3 = new FileInfo(); file1.ReadFile(); //file1.OpenBinaryFile(); //コンパイル時エラー //file1.SearchFile("検索するテキスト"); //コンパイル時エラー file2.OpenBinaryFile(); file2.ReadFile(); //file2.SearchFile("検索するテキスト"); //コンパイル時エラー file3.Search("検索するテキスト"); //file3.ReadFile(); //コンパイル時エラー //file3.OpenBinaryFile(); //コンパイル時エラー } }
上記、FileInfoはIFileおよびIBinaryFileの2つのインターフェースを明示的に実装しています。インターフェースを複数実装する場合、明示的に実装することで混乱を避け、可読性を向上させることを推奨します。
インターフェースにはメソッド、属性、インデックス、イベントの宣言を含むことができます。
インターフェースにはプライベートメンバー、プロテクテッドメンバー、内部メンバーを含むことができません。デフォルトでは、すべてのメンバーが公開されます。
インターフェースにはフィールドや自動実装の属性を含むことができません。
クラスや構造体は、インターフェースを実装する際に、public修飾子を使用して暗黙的な実装を行います。明示的な実装の場合は、それを使用しないでください。
インターフェースを実装するには、InterfaceName. MemberName を明示的に使用します。
一つのインターフェースは、一つまたは複数のインターフェースを継承できます。