Quick start manual

Object interfaces
10-9
Interface references
Interface references
If you declare a variable of an interface type, the variable can reference instances of
any class that implements the interface. Such variables allow you to call interface
methods without knowing at compile time where the interface is implemented. But
they are subject to the following:
An interface-type expression gives you access only to methods and properties
declared in the interface, not to other members of the implementing class.
An interface-type expression cannot reference an object whose class implements a
descendant interface, unless the class (or one that it inherits from) explicitly
implements the ancestor interface as well.
For example,
type
IAncestor = interface
end;
IDescendant = interface(IAncestor)
procedure P1;
end;
TSomething = class(TInterfacedObject, IDescendant)
procedure P1;
procedure P2;
end;
ƒ
var
D: IDescendant;
A: IAncestor;
begin
D := TSomething.Create; // works!
A := TSomething.Create; // error
D.P1; // works!
D.P2; // error
end;
In this example,
A is declared as a variable of type IAncestor. Because TSomething does not list
IAncestor among the interfaces it implements, a TSomething instance cannot be
assigned to A. But if we changed TSomething’s declaration to
TSomething = class(TInterfacedObject, IAncestor, IDescendant)
ƒ
the first error would become a valid assignment.
D is declared as a variable of type IDescendant. While D references an instance of
TSomething, we cannot use it to access TSomething’s P2 method, since P2 is not a
method of IDescendant. But if we changed D’s declaration to
D: TSomething;
the second error would become a valid method call.