При работе с интерфейсами в Delphi часто возникают вопросы, связанные с приведением типов. В частности, разработчики сталкиваются с проблемой приведения базового интерфейса к производному. Давайте разберемся в этом вопросе на примере.
Проблема
В Delphi интерфейсы не наследуются так, как классы. Если интерфейс IDerived наследует методы из IBase, то объект, реализующий IDerived, не подразумевает автоматическое реалирование IBase. Это означает, что приведение объекта базового интерфейса к производному интерфейсу не будет успешным без дополнительных условий.
Пример
type
IBase = interface(IInterface)
function Test: AnsiString;
end;
TBase = class(TInterfacedObject, IBase)
function Test: AnsiString;
end;
IDerived = interface(IBase)
function Test2: AnsiString;
end;
TDerived = class(TBase, IDerived)
function Test: AnsiString;
function Test2: AnsiString;
end;
{ TBase }
function TBase.Test: AnsiString;
begin
Result := 'Base Test';
end;
{ TDerived }
function TDerived.Test: AnsiString;
begin
Result := 'Derived Test';
end;
function TDerived.Test2: AnsiString;
begin
Result := 'Derived Test2';
end;
procedure TForm1.Button1Click(Sender: TObject);
var
b: IBase;
d: IDerived;
begin
b := TBase.Create;
d := b as IDerived; // Ошибка: Интерфейс не поддерживается
ShowMessage(b.Test);
end;
Ошибка
В приведенном выше коде мы пытаемся привести объект b, который реализует интерфейс IBase, к интерфейсу IDerived. Однако TBase реализует только IBase, и, следовательно, приведение типов вызывает ошибку, потому что TBase не реализует IDerived.
Решения
Изменить объявление TBase на TBase = class(TInterfacedObject, IBase, IDerived) и реализовать методы IDerived в TBase.
Изменить b := TBase.Create; на b := TDerived.Create;, чтобы объект b реализовывал оба интерфейса.
Пример кода, как в Delphi
function TXMLBook.Get_Id: IXMLId;
begin
Result := ChildNodes['id'] as IXMLId;
end;
Здесь ChildNodes['id'] возвращает базовый тип IXMLNode, который затем приводится к производному типу IXMLId. В Delphi это работает корректно, если объект поддерживает необходимый интерфейс.
Заключение
Для корректного приведения типов в Delphi необходимо убедиться, что объект реализует все необходимые интерфейсы. Это основное правило, которое нужно помнить при работе с интерфейсами и их приведением в Delphi.
В контексте рассматривается проблема приведения типов в Delphi при работе с интерфейсами, в частности, разбираются ошибки, возникающие при попытке приведения базового интерфейса к производному, и предлагаются решения для их устранения
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.