Интерфейсы могут быть реализованы классами и структурами. Указание на то, что класс или структура реализуют определенный интерфейс производится посредством включения идентификатора интерфейса в список базовых классов в определении класса или структуры.
Класс или структура, реализующие интерфейс, также неявно реализуют все его базовые интерфейсы.
При реализации интерфейса класс или структура могут определять явные реализации членов интерфейса. Явная реализация члена интерфейса - это метод, свойство или событие определение которого в качестве имени члена использует полностью квалифицированное имя члена интерфейса.
Такая реализация членов интерфейса может быть использована в случаях, когда по тем или иным причинам простое имя члена интерфейса не может быть использовано для его реализации в классе или структуре.
Невозможно обращение к члену, являющемуся явной реализацией члена интерфейса, через его полностью квалифицированное имя при вызове метода или обращении к свойству. Доступ к таким членам возможен только посредством получения ссылки на интерфейс и обращения к соответствующим членам по их простым именам.
Является ошибкой компиляции использование модификаторов доступа при определении такого члена. Также в определениях таких членов нельзя использовать модификаторы Abstract, Virtual, Override и Shared.
Класс или структура должны обеспечить реализацию всех членов интерфейсов, указанных в списке базовых в определении класса или структуры. Процесс определения реализаций членов интерфейса в реализующем их классе или структуре называется отображением интерфейса.
При отображении интерфейсов для класса или структуры C производится поиск реализации каждого члена каждого интерфейса, указанного в списке базовых для C. Реализация определенного интерфейсного члена I.M, где I - это имя интерфейса в котором определен член M, определяется путем анализа каждого класса или структуры S, начиная с C вверх по цепочке наследования, до тех пор пока соответствие не будет найдено:
Если S содержит явную реализацию члена интерфейса соответствующую I и M, то данный член рассматривается как реализация I.M.
В противном случае, если S содержит определение экземплярного открытого члена соответствующего M, то данный член рассматривается как реализация I.M.
Возникает ошибка компиляции если реализация какого-либо члена интерфейса, указанного в списке базовых для класса или структуры, не может быть найдена.
Для целей отображение интерфейсов член класса A считается соответствующим члену интерфейса B в следующих случаях:
A и B являются методами и их имена, список формальных параметров и тип возвращаемого значения являются идентичными.
A и B являются свойствами и их имена, тип и список формальных параметров являются идентичными. Также А должен иметь те же методы доступа, что определены в B.
A и B являются событиями и их имена и тип совпадают.
Важно учитывать следующие факторы при реализации членов интерфейсов:
Явные реализации членов интерфейсов имеют приоритет над другими членами классов или структур.
В отображении интерфейсов не участвуют статические члены и члены, не имеющие открытый доступ.
Если класс или структура реализует два или более интерфейса, содержащих члены с одинаковым именем, типом и списком параметров, является возможным отобразить все эти члены на единственный член класса или структуры.
Класс наследует все реализации интерфейсов, произведенные в его базовых классах.
Переопределение отображений интерфейсов, унаследованных от базовых классов, возможно только посредством повторной реализации интерфейсов.
Повторная реализация интерфейса, унаследованная от базового класса, производится путем включения данного интерфейса в список базовых в определении класса.
В этом случае класс должен реализовывать интерфейс как если бы он не наследовал его реализации от базового, т.е. должен содержать реализацию всех его членов.
Абстрактные классы наравне с обычными должны обеспечивать реализацию всех членов интерфейсов, определенных в качестве базовых для них. Обратите внимание, что явные реализации членов интерфейсов не могут быть абстрактными. Однако допускается вызов абстрактных методов в их реализации.
Interface IUserInterface1
Sub Test1();
Sub Test2();
End Interface;
Interface IUserInterface2
Sub Test2();
End Interface;
//Реализация интерфейсов
Class BaseClass: IUserInterface1, IUserInterface2
Public Sub Test1();
Begin
End Sub;
//Общий метод для двух интерфейсов
Public Sub Test2();
Begin
End Sub;
End Class;
//Повторная реализация интерфейса IUserInterface1
Class ChildClass: BaseClass, IUserInterface2
//Явная реализация метода IUserInterface2.Test2
Sub IUserInterface2.Test2();
Begin
End Sub;
End Class;
Sub Test();
Var
Obj: BaseClass = New BaseClass();
Obj1: ChildClass = New ChildClass();
Begin
Obj.Test1(); //Вызов метода BaseClass.Test1
(Obj As IUserInterface1).Test2(); //Вызов метода BaseClass.Test2
(Obj As IUserInterface2).Test2(); //Вызов метода BaseClass.Test2
Obj1.Test1(); //Вызов метода BaseClass.Test1
Obj1.Test2(); //Вызов метода BaseClass.Test2
(Obj1 As IUserInterface2).Test2(); //Вызов метода ChildClass.Test2
End Sub;
Interface IUserInterface
Sub Test1();
Sub Test2();
End Interface;
Abstract Class BaseAbstractClass: IUserInterface
Public Sub Test1();
Begin
//Реализация метода интерфейса
End Sub;
Public Sub Test2();
Begin
//Реализация метода интерфейса
Test3();
End Sub;
Abstract Public Sub Test3();
End Class;
Class UserObject: BaseAbstractClass
Public Override Sub Test3();
Begin
//Реализация абстрактного метода
End Sub;
End Class;
Sub Test();
Var
Obj: UserObject = New UserObject();
Begin
Obj.Test1(); //Вызов метода, реализованного в абстрактном классе
Obj.Test2(); //Вызов метода, реализованного в абстрактном классе
Obj.Test3(); //Вызов абстрактного метода, реализованного в классе UserObject
End Sub;
Interface IUserStruct
Property Title: string
Get;
Set;
End Property;
End Interface;
Struct UserStructure: IUserStruct
s: string;
Public Param1: integer;
Public Param2: double;
Public Property Title: string
Get
Begin
Return s;
End Get
Set
Begin
s := Value
End Set
End Property;
Constructor Create(Title: string; Param1Value: integer; Param2Value: double);
Begin
s := Title;
Param1 := Param1Value;
Param2 := Param2Value;
End Constructor;
End Struct;
Sub Test();
Var
StructObj: UserStructure;
Begin
StructObj := New UserStructure("Пользовательская структура", 100, 3.14);
End Sub;
См.также: