Por que minha classe implementa interfaces filho, mas não seus pais?

Eu encontrei um (pelo menos para mim) comportamento inesperado ao usar a herança de interface no Delphi.

Eu tenho essa hierarquia simples de classe e interface:

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

Eu queria declarar uma variável do tipoIMyBase. Crie umTMyObj e atribuí-lo à minha variável. IHMO, essa é uma prática normal de POO. Mas aconteceu que não compila.

Eu também tentei declarar uma variável do tipoIMyIntf e verifique se ele suportaIMyBase, IMHO deve apoiá-lo, mas não.

Aqui está um código de teste simples:

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.

Como você pode ver, tenho uma estrutura de classe / interface válida. mas algumas partes não são compiladas. e alguns não são executados conforme o esperado.

Porqueb := TMyObj.Create; dar um erro de tipo incompatível?PorqueSupports(i, IMyBase, b) retornafalse?Existe outra maneira (melhor) de resolver esse problema? sem um elenco duro sem cheque? (if i is IMyBase não funciona, porque as interfaces não suportamis operador.)

Este comportamento é válido para Pascal / Delphi ou é um bug? Na minha humilde opiniãoSupports() deve retornartrue. eTMyObj deve ser um válidoIMyBase (e, portanto, podem ser atribuídos).

questionAnswers(1)

yourAnswerToTheQuestion