// Этот интерфейс определяет поведение "наличия вершин".
public interface IPointy
{
// Неявно открытый и абстрактный.
byte GetNumberOfPoints();
}
}
В интерфейсах в C# 8 нельзя определять поля данных или нестатические конструкторы. Таким образом, следующая версия интерфейса IPointy
// Внимание! В этом коде полно ошибок!
public interface IPointy
{
// Ошибка! Интерфейсы не могут иметь поля данных!
public int numbOfPoints;
// Ошибка! Интерфейсы не могут иметь нестатические конструкторы!
public IPointy() { numbOfPoints = 0;}
}
В начальной версии интерфейса IPointy
IPointy можно было бы обновить, как показано ниже, закомментировав свойство для чтения-записи и добавив свойство только для чтения. Свойство Points заменяет метод GetNumberOfPoints().// Поведение "наличия вершин" в виде свойства только для чтения.
public interface IPointy
{
// Неявно public и abstract.
// byte GetNumberOfPoints();
// Свойство, поддерживающее чтение и запись,
// в интерфейсе может выглядеть так:
// string PropName { get; set; }
// Тогда как свойство только для записи - так:
byte Points { get; }
}
На заметку!
Интерфейсные типы также могут содержать определения событий (глава 12) и индексаторов (глава 11).Сами по себе интерфейсные типы совершенно бесполезны, поскольку выделять память для них, как делалось бы для класса или структуры, невозможно:
// Внимание! Выделять память для интерфейсных типов не допускается!
IPointy p = new IPointy(); // Ошибка на этапе компиляции!
Интерфейсы не привносят ничего особого до тех пор, пока не будут реализованы классом или структурой. Здесь IPointy
Hexagon) имеют вершины, в то время как другие (вроде Circle) — нет.Реализация интерфейса
Когда функциональность класса (или структуры) решено расширить за счет поддержки интерфейсов, к определению добавляется список нужных интерфейсов, разделенных запятыми. Имейте в виду, что непосредственный базовый класс должен быть указан первым сразу после операции двоеточия. Если тип класса порождается напрямую от System.Object
System.Object, если не задано иначе. К слову, поскольку структуры всегда являются производными от класса System.ValueType (см. главу 4), достаточно указать список интерфейсов после определения структуры. Взгляните на приведенные ниже примеры:// Этот класс является производными от System.Object
// и реализует единственный интерфейс.
public class Pencil : IPointy
{...}
// Этот класс также является производными от System.Object
// и реализует единственный интерфейс.
public class SwitchBlade : object, IPointy
{...}
// Этот класс является производными от специального базового
// класса и реализует единственный интерфейс.
public class Fork : Utensil, IPointy
{...}
// Эта структура неявно является производной
// от System.ValueType и реализует два интерфейса.
public struct PitchFork : ICloneable, IPointy
{...}