If the delegate property is of a class type, that class and its ancestors are searched for methods implementing the specified interface before the enclosing class and its ancestors are searched. Thus it is possible to implement some methods in the class specified by the property, and others in the class where the property is declared. Method resolution clauses can be used in the usual way to resolve ambiguities or specify a particular method. An interface cannot be implemented by more than one class-type property. For example,
type
IMyInterface = interface
procedure P1;
procedure P2;
end;
TMyImplClass = class
procedure P1;
procedure P2;
end;
TMyClass = class(TInterfacedObject, IMyInterface)
FMyImplClass: TMyImplClass;
property MyImplClass: TMyImplClass read
FMyImplClass implements IMyInterface;
procedure IMyInterface.P1 = MyP1;
procedure MyP1;
end;
procedure
TMyImplClass.P1;
...
procedure
TMyImplClass.P2;
...
procedure
TMyClass.MyP1;
...
var
MyClass: TMyClass;
MyInterface: IMyInterface;
begin
MyClass := TMyClass.Create;
MyClass.FMyImplClass := TMyImplClass.Create;
MyInterface := MyClass;
MyInterface.P1; // calls TMyClass.MyP1;
MyInterface.P2; // calls TImplClass.P2;
end;
Implementing interfaces by delegation
如果委托属性是一个类类型,那么在委托属性声明所在的类及其祖先类被搜索之前,将在委托属性所属的类及其祖先类中搜索实现指定接口的方法。(在下面的例子中,委托属性声明所在的类是TMyClass,委托属性所属的类是TMyImplClass。)由此可见,在由属性指定的类中实现一些方法而该类中声明了其他的属性,这是可能的。方法决定子句通常被用于解决不明确或特别指定的方法。接口不能被多于一个类类型属性实现。例如,
type
IMyInterface = interface
procedure P1;
procedure P2;
end;
TMyImplClass = class
procedure P1;
procedure P2;
end;
TMyClass = class(TInterfacedObject, IMyInterface)
FMyImplClass: TMyImplClass;
property MyImplClass: TMyImplClass read
FMyImplClass implements IMyInterface;
procedure IMyInterface.P1 = MyP1;
procedure MyP1;
end;
procedure
TMyImplClass.P1;
...
procedure
TMyImplClass.P2;
...
procedure
TMyClass.MyP1;
...
var
MyClass: TMyClass;
MyInterface: IMyInterface;
begin
MyClass := TMyClass.Create;
MyClass.FMyImplClass := TMyImplClass.Create;
MyInterface := MyClass;
MyInterface.P1; //调用TMyClass.MyP1;
MyInterface.P2; //调用TImplClass.P2;
end;