English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
В человеческом мире договорные обязательства约束两个或 более людей выполнять свои обязательства по договору. Таким же образом, интерфейс включает в себя декларации связанных функций. Сущность, реализующая интерфейс, должна предоставить реализацию декларированных функций.
В 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); //Ошибка: метод не может быть реализован } }
Класс или структура может использовать двоеточие (:) для реализации одного или нескольких интерфейсов.
Синтаксис:
<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. Он определяет всех членов интерфейса IFile с помощью модификатора доступа public. Класс 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 to be searched")//ошибка компиляции file2.Search("text to be searched"); //file2.ReadFile(); //ошибка компиляции //file2.WriteFile("content"); //ошибка компиляции } }
В примере выше, объект file1 может обращаться только к членам IFile, а file2 может обращаться только к членам класса FileInfo. Это ограниченность явного выполнения.
Класс или структура могут реализовывать несколько интерфейсов. Он должен предоставить реализацию всех членов всех интерфейсов.
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(); //ошибка компиляции //file1.SearchFile("text to be searched"); //ошибка компиляции file2.OpenBinaryFile(); file2.ReadFile(); //file2.SearchFile("text to be searched"); //ошибка компиляции file3.Search("text to be searched"); //file3.ReadFile(); //ошибка компиляции //file3.OpenBinaryFile(); //ошибка компиляции } }
Верх, FileInfo реализует два интерфейса, IFile и IBinaryFile, явно реализованы. Рекомендуется явно реализовывать интерфейсы при реализации нескольких интерфейсов, чтобы избежать путаницы и улучшить читаемость.
Интерфейс может содержать объявления методов, свойств, индексаторов и событий.
Интерфейс не может содержать частные члены, защищенные члены или внутренние члены. По умолчанию, все члены являются общедоступными.
Интерфейс не может содержать поля и автоматически реализуемые свойства.
Класс или структура могут隐но или явно реализовать один или несколько интерфейсов. При隐ном выполнении интерфейса используйте модификатор public, а в случае явного выполнения - не используйте его.
Используйте InterfaceName. MemberName для явного выполнения интерфейса.
Одна интерфейс может наследовать один или несколько интерфейсов.