English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# 接口(Interface)

In der menschlichen Welt binden Verträge zwischen zwei oder mehr Personen daran, gemäß dem Vertrag zu handeln. Ebenso enthalten Schnittstellen Deklarationen von verwandten Funktionen. Die Entitäten, die eine Schnittstelle implementieren, müssen die Implementierung der deklarierten Funktionen bereitstellen.

In C# kann mit dem Schlüsselwort ‘interface’ eine Schnittstelle definiert werden. Eine Schnittstelle kann Methoden, Eigenschaften, Indexer und Ereignisdeklarationen enthalten. Sie kann jedoch keine Felder oder automatisch generierte Eigenschaften enthalten.

Nachfolgend ist eine Schnittstellenbeschreibung mit einigen grundlegenden Funktionen für Dateioperationen.

interface IFile
{
    void ReadFile();
    void WriteFile(string text);
}

Sie können keinen Zugriffsmodifikator auf die Mitglieder einer Schnittstelle anwenden. Standardmäßig sind alle Mitglieder öffentlich. Verwenden Sie Sie einen Zugriffsmodifikator in einer Schnittstelle, wird der C#-Kompilierer die Kompilierungszeitfehler ‘Der Modifikator ‘public’ ausgeben./private/‘protected’ ist nicht gültig für dieses Element. (Visual Studio zeigt sofort einen Fehler an und führt keine Kompilierung durch.)

interface IFile
{
    protected void ReadFile(); //Kompilierungsfehler
    private void WriteFile(string text);//Kompilierungsfehler
}

接口只能包含声明,而不能包含实现。以下将给出编译时错误。

interface IFile
{
    void ReadFile();
    void WriteFile(string text){
        Console.Write(text);  //错误:无法实现方法
    }
}

实现接口

一个类或一个Struct可以使用冒号(:)实现一个或多个接口。  

语法:

<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("Writing to file");
    }
}

在上面的示例中,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("Writing to file");
    }
}

在显式实现接口时,只能通过接口类型的实例访问接口成员。

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("Writing to file");
    }
    public void Search(string text)
    {
        Console.WriteLine("Searching in file");
    }
}
public class Program
{
    public static void Main()
    {
        IFile file1 = new FileInfo();
        FileInfo file2 = new FileInfo();
        file1.ReadFile(); 
        file1.WriteFile("content"); 
        //file1.Search("text zu durchsuchen")//Kompilierungsfehler 
        
        file2.Search("text zu durchsuchen");
        //file2.ReadFile(); //Kompilierungsfehler 
        //file2.WriteFile("content"); //Kompilierungsfehler 
    }
}

Im obigen Beispiel ist file1Der Objekt kann nur auf die Mitglieder IFile zugreifen und file2Es kann nur auf die Mitglieder der FileInfo-Klasse zugegriffen werden. Dies ist eine Beschränkung der expliziten Implementierung.

Implementierung mehrerer Schnittstellen

Eine Klasse oder Struktur kann mehrere Schnittstellen implementieren. Sie muss die Implementierung aller Mitglieder aller Schnittstellen bereitstellen.

interface IFile
{
    void ReadFile();
}
interface IBinaryFile
{
    void OpenBinaryFile();
    void ReadFile();
}
class FileInfo : IFile, IBinaryFile
{
    void IFile.ReadFile()
    {
        Console.WriteLine("Reading Text File");
    }
    void IBinaryFile.OpenBinaryFile()
    {
        Console.WriteLine("Opening Binary File");
    }
    void IBinaryFile.ReadFile()
    {
        Console.WriteLine("Reading Binary File");
    }
    public void Search(string text)
    {
        Console.WriteLine("Searching in File");
    }
}
public class Program
{
    public static void Main()
    {
        IFile file1 = new FileInfo();
        IBinaryFile file2 = new FileInfo();
        FileInfo file3 = new FileInfo();
        file1.ReadFile(); 
        //file1.OpenBinaryFile(); //Kompilierungsfehler 
        //file1.SearchFile("text zu durchsuchen"); //Kompilierungsfehler 
        
        file2.OpenBinaryFile();
        file2.ReadFile();
        //file2.SearchFile("text zu durchsuchen"); //Kompilierungsfehler 
    
        file3.Search("text zu durchsuchen");
        //file3.ReadFile(); //Kompilierungsfehler 
        //file3.OpenBinaryFile(); //Kompilierungsfehler 
    }
}

Oben hat FileInfo zwei Schnittstellen implementiert, IFile und IBinaryFile, explizit implementiert. Es wird empfohlen, Schnittstellen explizit zu implementieren, wenn mehrere Schnittstellen implementiert werden, um Verwirrung zu vermeiden und die Lesbarkeit zu verbessern.

要记住的要点:
  1. 接口可以包含方法,属性,索引器和事件的声明。

  2. 接口不能包含私有成员,受保护成员或内部成员。默认情况下,所有成员都是公开的。

  3. 接口不能包含字段和自动实现的属性。

  4. 类或结构可以隐式或明确实现一个或多个接口。在隐式实现接口时使用public修饰符,而在明确实现的情况下请勿使用它。

  5. 使用 InterfaceName. MemberName 明确实现接口。

  6. 一个接口可以继承一个或多个接口。