Once an
interface has been declared, it must be implemented in a class before it can be
used. The interfaces implemented by a class are specified in the class’s
declaration, after the name of the class’s ancestor. Such declarations have the
form
type className
= class (ancestorClass, interface1, ..., interfacen)
memberList
end;
For
example,
type
TMemoryManager = class(TInterfacedObject,
IMalloc, IErrorInfo)
...
end;
declares a class called TMemoryManager
that implements the IMalloc and IErrorInfo interfaces. When a class
implements an interface, it must implement (or inherit an implementation of)
each method declared in the interface.
Here is
the declaration of TInterfacedObject in the System unit.
type
TInterfacedObject
= class(TObject, IInterface)
protected
FRefCount: Integer;
function
QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef:
Integer; stdcall;
function _Release:
Integer; stdcall;
public
procedure
AfterConstruction; override;
procedure
BeforeDestruction; override;
class function
NewInstance: TObject; override;
property RefCount:
Integer read FRefCount;
end;
TInterfacedObject implements the IInterface interface. Hence TInterfacedObject
declares and implements each of IInterface’s three methods.
Classes
that implement interfaces can also be used as base classes. (The first example
above declares TMemoryManager as a direct descendent of TInterfacedObject.)
Since every interface inherits from IInterface, a class that implements
interfaces must implement the QueryInterface, _AddRef, and _Release
methods. The System unit’s TInterfacedObject implements these
methods and is thus a convenient base from which to derive other classes that
implement interfaces.
When an
interface is implemented, each of its methods is mapped onto a method in the
implementing class that has the same result type, the same calling convention,
the same number of parameters, and identically typed parameters in each
position. By default, each interface method is mapped to a method of the same
name in the implementing class.
Changing inherited
implementations
Implementing interfaces by delegation
一旦一个接口被声明,那么在使用该接口之前必须实现该接口。在类声明中、类的祖先名称之后,接口该声明中指定的一个类实现。声明形式如下:
type className
= class (ancestorClass, interface1, ..., interfacen)
memberList
end;
例如,
type
TMemoryManager = class(TInterfacedObject,
IMalloc, IErrorInfo)
...
end;
这里声明了一个叫做TMemoryManager的类,该类实现了IMalloc和IErrorInfo接口。当一个类实现一个接口时,它必须实现(或者继承实现)接口中的每个方法。
下面是System单元中TInterfaceObject的声明:
type
TInterfacedObject
= class(TObject, IInterface)
protected
FRefCount: Integer;
function
QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef:
Integer; stdcall;
function _Release:
Integer; stdcall;
public
procedure
AfterConstruction; override;
procedure
BeforeDestruction; override;
class function
NewInstance: TObject; override;
property RefCount:
Integer read FRefCount;
end;
TInterfacedObject类实现了IInterface接口。因此声明TInterfacedObject类并实现了IInterface的三个方法中的每一个。
实现接口的类也可以作为基本类被使用。(上面第一个例子中,将TMemoryManager作为TInterfaceObject的一个直接后裔声明。)因为所有接口都继承自IInterface,所以实现接口的类必须实现QueryInterface、_AddRef和_Release这三个方法。System单元中的TInterfaceObject类实现了这些方法,因而为从该类派生其他用于实现接口的类提供了便利的基础。
当一个接口被实现时,它的每个方法都映射到实现类中的某个方法,并且具有相同的结果类型,相同的调用约定,相同的参数个数,相应位置的参数类型等同。缺省情况下,每个接口方法在实现类中映射到同名方法上。