На заметку!
Изменения интерфейсов в версии C# 8 являются, по всей видимости, наиболее существенными изменениями существующего языка за весь обозримый период. Как было ранее описано, новые возможности интерфейсов значительно приближают их функциональность к функциональности абстрактных классов с добавочной способностью классов реализовывать множество интерфейсов. В этой области рекомендуется проявлять надлежащую осторожность и здравый смысл. Один лишь факт, что вы можете что-то делать, вовсе не означает, что вы обязаны поступать так.Определение специальных интерфейсов
Теперь, когда вы лучше понимаете общую роль интерфейсных типов, давайте рассмотрим пример определения и реализации специальных интерфейсов. Скопируйте файлы Shape.cs
Hexagon.cs, Circle.cs и ThreeDCircle.cs из решения Shapes, созданного в главе 6. Переименуйте пространство имен, в котором определены типы, связанные с фигурами, в CustomInterfасе (просто чтобы избежать импортирования в новый проект определений пространства имен). Добавьте в проект новый файл по имени IPointy.cs.На синтаксическом уровне интерфейс определяется с использованием ключевого слова interface
System.Object; тем не менее, как будет показано позже в главе, можно задавать базовые интерфейсы). До выхода C# 8.0 для членов интерфейса не указывались модификаторы доступа (т.к. все члены интерфейса были неявно открытыми и абстрактными). В версии C# 8.0 можно также определять члены private, internal, protected и даже static, о чем пойдет речь далее в главе. Ниже приведен пример определения специального интерфейса в С#:namespace CustomInterfaces
{
// Этот интерфейс определяет поведение "наличия вершин".
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) — нет.Реализация интерфейса
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT