И нет такой директивы компилятора, о которой Дэнни думал, что она может существовать.

аружил (по крайней мере для меня) неожиданное поведение при использовании наследования интерфейса в Delphi.

У меня есть эта простая иерархия классов и интерфейсов:

+---------------+
| << IMyBase >> |
+---------------+
        ^
        |
+---------------+
| << IMyIntf >> |
+---------------+
        ^
        |
   +---------+
   | TMyObj  |
   +---------+

Я хотел объявить переменную типаIMyBase, СоздатьTMyObj и назначьте его моей переменной. IHMO это нормальная ООП практика. Но оказалось, что он не компилируется.

Я также пытался объявить переменную типаIMyIntf и проверьте, поддерживает ли онIMyBaseИМХО, это должно поддерживать, но это не так.

Вот простой тестовый код:

program interface_inheritance;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  IMyBase = interface
    ['{CC7C61B8-3FBA-481F-AF0D-A93C603B5202}']
    procedure Hello;
  end;

  IMyIntf = interface(IMyBase)
    ['{01CE01D9-A753-431C-A30E-64BAEC6C4E26}']
    //
  end;

  TMyObj = class(TInterfacedObject, IMyIntf)
    procedure Hello;
  end;

{ TMyObj }

procedure TMyObj.Hello;
begin
  Writeln('Hello World');
end;

var
  b: IMyBase;
  i: IMyIntf;
begin
(*  // Compile Error E2010
  b := TMyObj.Create;
  b.Hello;*)

  // Does not work as Expected
  // Does not call Hello()
  i := TMyObj.Create;
  if Supports(i, IMyBase, b) then begin
    // Why does i not support IMyBase ??
    b.Hello;
  end;

  // Works but unsafe!
  // Hard cast, without check.
  i := TMyObj.Create;
  b := IMyBase(i);
  b.Hello;

  // Works, of course!
  i := TMyObj.Create;
  i.Hello;

  Readln;
end.

Как вы можете видеть, у меня есть допустимая структура класса / интерфейса. но некоторые части не компилируются. а некоторые не выполняют, как ожидалось.

Почемуb := TMyObj.Create; дать ошибку несовместимого типа?ПочемуSupports(i, IMyBase, b) возвращаетсяfalse?Есть ли другой (лучший) способ решить такую ​​проблему? без жесткого броска без проверки? (if i is IMyBase не работает, потому что интерфейсы не поддерживаютis оператор).

Это правильное поведение Pascal / Delphi или ошибка? ИМХОSupports() должен вернутьсяtrue, а такжеTMyObj должен быть действительнымIMyBase (и поэтому быть назначаемым).

Ответы на вопрос(1)

Ваш ответ на вопрос