// Общий интерфейс
ISomeIntf = interface
procedure SomeProc;
end;
// Общая реализация интерфейса
TSomeIntfImpl = class(TAggregatedObject, ISomeIntf)
public
procedure SomeProc;
end;
// Класс, наследующий интерфейс ISomeIntf с его реализацией в классе TSomeIntfImpl
TBar = class(TInterfacedObject, ISomeIntf)
private
FSomeIntfImpl: TSomeIntfImpl;
function GetSomeIntfImpl: ISomeIntf;
protected
property SomeIntfImpl: ISomeIntf read GetSomeIntfImpl implements ISomeIntf;
public
constructor Create;
destructor Destroy; override;
end;
...
constructor TBar.Create;
begin
inherited Create;
FSomeIntfImpl := TSomeIntfImpl.Create(Self);
end;
destructor TBar.Destroy;
begin
FSomeIntfImpl.Free;
inherited Destroy;
end;
function TBar.GetSomeIntfImpl: ISomeIntf;
begin
Result := FSomeIntfImpl;
end;
Таким образом, класс TBar наследует интерфейс ISomeIntf и делегирует его реализацию классу TSomeIntfImpl. Таким же образом, мы можем создать и другие классы, кроме TBar, и писать для них полиморфный код, имея на руках ссылку на интерфейс ISomeIntf.
TSomeIntfImpl объявлен как потомок TAggregatedObject. Это важно, так как в этом классе методы интерфейса IInterface реализованы таким образом, что просто передают вызовы внешнему объекту. Если бы TSomeIntfImpl сам реализовал эти методы, то клиент не смог бы, имея на руках ссылку на ISomeIntf получить другой интерфейс, даже если класс TBar его и поддерживал. Кроме того, при запросе ISomeIntf счетчик ссылок увеличивался бы не у экземпляра TBar, как следовало бы, а у внутреннего объекта класса TSomeIntfImpl.