Реализация интерфейсов

Интерфейсы могут быть реализованы классами и структурами. Указание на то, что класс или структура реализуют определенный интерфейс производится посредством включения идентификатора интерфейса в список базовых классов в определении класса или структуры.

Класс или структура, реализующие интерфейс, также неявно реализуют все его базовые интерфейсы.

Явная реализация членов интерфейсов

При реализации интерфейса класс или структура могут определять явные реализации членов интерфейса. Явная реализация члена интерфейса - это метод, свойство или событие определение которого в качестве имени члена использует полностью квалифицированное имя члена интерфейса.

Такая реализация членов интерфейса может быть использована в случаях, когда по тем или иным причинам простое имя члена интерфейса не может быть использовано для его реализации в классе или структуре.

Невозможно обращение к члену, являющемуся явной реализацией члена интерфейса, через его полностью квалифицированное имя при вызове метода или обращении к свойству. Доступ к таким членам возможен только посредством получения ссылки на интерфейс и обращения к соответствующим членам по их простым именам.

Является ошибкой компиляции использование модификаторов доступа при определении такого члена. Также в определениях таких членов нельзя использовать модификаторы Abstract, Virtual, Override и Shared.

Отображение интерфейсов

Класс или структура должны обеспечить реализацию всех членов интерфейсов, указанных в списке базовых в определении класса или структуры. Процесс определения реализаций членов интерфейса в реализующем их классе или структуре называется отображением интерфейса.

При отображении интерфейсов для класса или структуры C производится поиск реализации каждого члена каждого интерфейса, указанного в списке базовых для C. Реализация определенного интерфейсного члена I.M, где I - это имя интерфейса в котором определен член M, определяется путем анализа каждого класса или структуры S, начиная с C вверх по цепочке наследования, до тех пор пока соответствие не будет найдено:

Возникает ошибка компиляции если реализация какого-либо члена интерфейса, указанного в списке базовых для класса или структуры, не может быть найдена.

Для целей отображение интерфейсов член класса A считается соответствующим члену интерфейса B в следующих случаях:

Важно учитывать следующие факторы при реализации членов интерфейсов:

Если класс или структура реализует два или более интерфейса, содержащих члены с одинаковым именем, типом и списком параметров, является возможным отобразить все эти члены на единственный член класса или структуры.

Наследование реализации интерфейсов

Класс наследует все реализации интерфейсов, произведенные в его базовых классах.

Переопределение отображений интерфейсов, унаследованных от базовых классов, возможно только посредством повторной реализации интерфейсов.

Повторная реализация интерфейсов

Повторная реализация интерфейса, унаследованная от базового класса, производится путем включения данного интерфейса в список базовых в определении класса.

В этом случае класс должен реализовывать интерфейс как если бы он не наследовал его реализации от базового, т.е. должен содержать реализацию всех его членов.

Абстрактные классы и интерфейсы

Абстрактные классы наравне с обычными должны обеспечивать реализацию всех членов интерфейсов, определенных в качестве базовых для них. Обратите внимание, что явные реализации членов интерфейсов не могут быть абстрактными. Однако допускается вызов абстрактных методов в их реализации.

Пример 1

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;

Пример 2

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;

Пример 3

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("Пользовательская структура"1003.14);
End Sub;

См.также:

Интерфейсы