TAClass
является конкретной реализацией интерфейса IIntfA
через
делегирование интерфейса, но почему TBClass
, который является потомком TAClass
,
не считается конкретной реализацией IIntfA
интерфейса?
Краткий ответ: проблема не в IIntfA
, а в неполном IIntfB
.
Длинный ответ: Наследование интерфейса - это наследуемое наследование C ++, которое иногда не является интуитивно понятным.
В примере:
IIntfB = interface(IIntfA)
procedure writeB();
end;
на самом деле можно записать как
IIntfB = interface
procedure writeA();
procedure writeB();
end;
При реализации нескольких интерфейсов общие части не используются повторно. Компилятор устанавливает отдельные таблицы из методов реализации, таких как:
TADelegateClass:
QueryInterface(IIntfA) = Self.vtable_IIntfA
vtable_IIntfA.writeA <- Self.writeA
TAClass:
QueryInterface(IIntfA) = delegateA.vtable_IIntfA
TBClass:
QueryInterface(IIntfA) = inherited delegateA.vtable_IIntfA
QueryInterface(IIntfB) = vtable_IIntfB
vtable_IIntfB.writeA <- (this is missing!)
vtable_IIntfB.writeB <- Self.writeB
TBClass действительно не имеет реализации IIntfB.writeA
.
Это можно проверить, вручную назначив метод для определенного интерфейса и наблюдая за исчезновением ошибки:
TBClass = class(TAClass, IIntfB)
public
procedure IIntfB.writeA = writeB;
// dummy method, shows IIntfB.writeA is missing
К сожалению, я не знаю, как сказать компилятору доступ к отображению из другого интерфейса. Кстати, у Delphi та же ошибка / недостаток.