Interface Implementation

Interfaces may be implemented by classes and structures. To indicate that a class or structure implements an interface, the interface identifier is included in the base class list of the class or structure.

A class or structure that implements an interface also implicitly implements all of the interface's base interfaces.

Explicit Interface Member Implementation

For purposes of implementing interfaces, a class or structure may declare explicit interface member implementations. An explicit interface member implementation is a method, property, or event declaration, which uses a fully qualified interface member name as the member name.

Explicit interface member implementation is used when the simple name of an interface member may not be appropriate to implement it in a class or structure due to some reasons.

It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation or property access. Such members can only be accessed through an interface reference, and are in that case referenced simply by their member names.

It is a compile error for an explicit interface member implementation to include an access modifier. The following modifiers cannot be used to declare such members: Abstract, Virtual, Override and Shared.

Interface Mapping

A class or structure must provide implementations of all members of the interfaces that are specified in the class or structure declaration. The process of locating implementations of interface members in an implementing class or structure is known as interface mapping.

Interface mapping for a class or structure C locates an implementation for each member of each interface specified in the base class list of C. The implementation of a particular interface member I.M, where I is the interface, in which the member M is declared, is determined by examining each class or structure S, starting with C and repeating for each successive base class of C, until a match is located:

A compile error occurs if implementation cannot be located for an interface member specified in the base class list of the class or structure.

For purposes of interface mapping, a class member A matches an interface member B when:

The following factors are important for interface member implementation:

If a class or structure implements two or more interfaces containing a member with the same name, type, and parameter types, it is possible to map each of these interface members onto a single class or structure member.

Interface Implementation Inheritance

A class inherits all interface implementations executed in its base classes.

Without explicitly reimplementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes.

Interface Reimplementation

An interface is reimplemented by including this interface in the base class list in the class declaration.

In this case a class should implement an interface as if it did not inherit its implementation from the base class, that is, it should contain implementation of all its members.

Abstract Classes and Interfaces

Like a non-abstract class, an abstract class must provide implementations of all members of the interfaces that are listed in the base class list of the class. Note that explicit interface member implementations cannot be abstract. But abstract methods can be called in their implementation.

Example 1

Interface IUserInterface1
    Sub Test1();
    Sub Test2();
End Interface;

Interface IUserInterface2
    Sub Test2();
End Interface;

//Interface implementation
Class BaseClass: IUserInterface1, IUserInterface2
    Public Sub Test1();
    Begin
        
    End Sub;
    //Common method for two interfaces
    Public Sub Test2();
    Begin
        
    End Sub;
End Class;

//Repetitive implementation of the IUserInterface1 interface
Class ChildClass: BaseClass, IUserInterface2
    //Explicit implementation of the IUserInterface2.Test2 method
    Sub IUserInterface2.Test2();
    Begin
        
    End Sub;
End Class;

Sub Test();
Var
    Obj: BaseClass = New BaseClass();
    Obj1: ChildClass = New ChildClass();
Begin
    Obj.Test1(); //Invocation of the BaseClass.Test1 method
    (Obj As IUserInterface1).Test2(); //Invocation of the  BaseClass.Test2 method
    (Obj As IUserInterface2).Test2(); //Invocation of the BaseClass.Test2 method
    
    Obj1.Test1(); //Invocation of the BaseClass.Test1 method
    Obj1.Test2(); //Invocation of the BaseClass.Test2 method
    (Obj1 As IUserInterface2).Test2(); //Invocation of the ChildClass.Test2 method
End Sub;

Example 2

Interface IUserInterface
    Sub Test1();
    Sub Test2();
End Interface;

Abstract Class BaseAbstractClass: IUserInterface
    Public Sub Test1();
    Begin
        //Interface method implementation
    End Sub;
    
    Public Sub Test2();
    Begin
        //Interface method implementation
        Test3();
    End Sub;
    
    Abstract Public Sub Test3();
End Class;

Class UserObject: BaseAbstractClass
    Public Override Sub Test3();
    Begin
        //Abstract method implementation
    End Sub;
End Class;

Sub Test();
Var
    Obj: UserObject = New UserObject();
Begin
    Obj.Test1(); //Invocation of a method implemented in abstract class
    Obj.Test2(); //Invocation of method implemented in abstract class
    Obj.Test3(); //Invocation of abstract method implemented in the Object class
End Sub;

Example 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("User structure"1003.14);
End Sub;

See also:

Interfaces