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.
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.
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:
If S contains an explicit interface member implementation that matches I and M, this member is regarded as the implementation of I.M.
Otherwise, if S contains a declaration of a non-static public member that matches M, this member is the implementation of I.M.
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:
A and B are methods, and the name, formal parameter lists, and returned value type of A and B are identical.
A and B are properties, the name, type and formal parameter lists of A and B are identical. A should also have the same access methods as determined in B.
A and B are events, and the name and type of A and B are identical.
The following factors are important for interface member implementation:
Explicit interface member implementations take precedence over other class or structure members.
Neither non-public nor static members participate in interface mapping.
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.
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.
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.
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.
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;
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;
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", 100, 3.14);
End Sub;
See also: