По работе захотел воспользоваться паттерном фабричный метод, и спрятать конструктор за protected декларацию.
program ProtectedConstructor;
{$APPTYPE CONSOLE}
{$R *.res}
uses
  System.SysUtils;
  type
    TBaseClass = class
    protected
      FData : string;
      constructor Create(const AData: string); virtual;
    public
      class function FactoryMethod(const Adata: string): TBaseClass;
      property Data : string read FData;
    end;
  type
    TInheritor = class (TBaseClass)
    protected
      constructor Create(const AData: string); override;
    end;
constructor TBaseClass.Create(const AData: string);
begin
  Fdata := Adata;
  Writeln('TBaseClass.Create');
end;
class function TBaseClass.FactoryMethod(const Adata: string): TBaseClass;
begin
  Result := TInheritor.Create(Adata)
end;
constructor TInheritor.Create(const AData: string);
begin
  inherited;
  Writeln('TInheritor.Create');
end;
var
  MyClass : TBaseClass;
begin
  try
    MyClass := TBaseClass.FactoryMethod('Test');
    try
      Writeln(MyClass.Data);
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
    MyClass.Free;
    Readln;
  end;
end.
Ожидаемое поведение:
Я же решил разнести классы по разным модулям. TBaseClass в одном, и TInheritor в другом.
program BugProtectedConstructor;
{$APPTYPE CONSOLE}
{$R *.res}
uses
  System.SysUtils,
  uBaseClass in 'uBaseClass.pas',
  uInheritor in 'uInheritor.pas';
var
  MyClass : TBaseClass;
begin
  try
    MyClass := TBaseClass.FactoryMethod('Test');
    try
      Writeln(MyClass.Data);
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
    MyClass.Free;
    Readln;
  end;
end.
unit uBaseClass;
interface
  type
    TBaseClass = class
    protected
      FData : string;
      constructor Create(const AData: string); virtual;
    public
      class function FactoryMethod(const Adata: string): TBaseClass;
      property Data : string read FData;
    end;
implementation
uses
  uInheritor;
constructor TBaseClass.Create(const AData: string);
begin
  Fdata := Adata;
  Writeln('TBaseClass.Create');
end;
class function TBaseClass.FactoryMethod(const Adata: string): TBaseClass;
begin
  Result := TInheritor.Create(Adata)
end;
end.
unit uInheritor;
interface
uses
  uBaseClass;
  type
    TInheritor = class (TBaseClass)
    protected
      constructor Create(const AData: string); override;
    end;
implementation
{ TInheritorOne }
constructor TInheritor.Create(const AData: string);
begin
  inherited;
  Writeln('TInheritor.create');
end;
end.
На выходе:
То есть в перегруженный конструктор мы не попадаем.
И вот вопрос, это баг или фича?
Запостил в quality portal
https://quality.embarcadero.com/browse/RSP-29333

