Помощники интерфейса или делегирование родительского интерфейса - PullRequest
2 голосов
/ 21 апреля 2010

Если у меня есть существующий потомок IInterface, реализованный третьей стороной, и я хочу добавить вспомогательные процедуры, предоставляет ли Delphi какой-либо простой способ сделать это без перенаправления каждого метода интерфейса вручную? То есть, учитывая интерфейс, подобный так:

IFoo = interface
  procedure Foo1;
  procedure Foo2;
  ...
  procedure FooN;
end;

Поддерживается ли что-либо похожее на следующее?

IFooHelper = interface helper for IFoo
  procedure Bar;
end;

или

IFooBar = interface(IFoo)
  procedure Bar;
end;

TFooBar = class(TInterfacedObject, IFoo, IFooBar)
private
  FFoo: IFoo;
public
  procedure Bar;
  property Foo: IFoo read FFoo implements IFoo;
end;

Меня особенно интересуют способы, позволяющие мне всегда вызывать Foo1, Foo2 и Bar с одной ссылкой на переменную (IFoo, IFooBar или TFooBar), без переключения между ними и без добавления всех методов IFoo в TFooBar.

Ответы [ 3 ]

1 голос
/ 21 апреля 2010

Вы не можете получить доступ к методам IFoo через ссылку на TFooBar , потому что TFooBar не реализует IFoo - делегирует IFoo . Но вам все равно не следует использовать ссылку TFooBar для доступа к интерфейсному объекту, в этом и заключается весь смысл использования интерфейсов!

ПРИМЕЧАНИЕ: Чтобы сознательно предотвратить это, я принимаю соглашение о реализации методов интерфейса в моих классах как «защищенных», в частности, чтобы запретить доступ к этим деталям реализации, кроме как через сам интерфейс.

Где бы вы в настоящее время не получали ссылку на TFooBar , измените ее, чтобы вместо этого получить интерфейс IFooBar , реализованный TFooBar и вы будете отсортированы.

1 голос
/ 21 апреля 2010

Измените свой класс на:

TFooBar = Class(TInterfacedObject, IFoo, IFooBar)
private
  FFoo: IFoo;
public
  procedure Bar;
  property Foo: IFoo read FFoo implements IFoo ;
end;

Вам также понадобится конструктор или какой-либо метод для создания экземпляра IFoo и помещения его в FFoo.

0 голосов
/ 21 апреля 2010

Я не уверен, что понял все ваши проблемы, но в любом случае вот мое предложение:

IFooBar = interface(IFoo)
  procedure Bar;
end;

TFooDelegate = class(TInterfacedObject, IFoo )
private
  FFoo: IFoo;
public
  property Foo: IFoo read FFoo implements IFoo;
end;

TFooBar = class( TFooDelegate, IFooBar )
  procedure Bar;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...