In DelphiLanguage, a variable of a type defined with a class of declaration.
This variable is assignment compatible with the ClassType? of the classes inherited from the class declared in variable type.
unit Dummy; interface type IMyObject = interface ['{DDF6CE40-55D1-11D5-B57E-00AA00ACFD08}'] procedure AMethod; end; IMyObjectClass = interface ['{DDF6CE41-55D1-11D5-B57E-00AA00ACFD08}'] function CreateInstance: IMyObject; end; type TMyObjectBase = class(TInterfacedObject) public class function CreateInstance: IMyObject; virtual; abstract; end; //Declaration of a class of type TMyObjectBaseClass = class of TMyObjectBase; TMyDelegator = class(TInterfacedObject,IMyObjectClass) private FMyObjectClass: TMyObjectBaseClass; function CreateInstance: IMyObject; constructor Create(AMyObjectClass: TMyObjectBaseClass); public class function CreateInterfaced?(AMyObjectClass: TMyObjectBaseClass): IMyObjectClass; end; type TFooObject = class(TMyObjectBase,IMyObject) private procedure AMethod; public class function CreateInstance: IMyObject; override; end; TBarObject = class(TMyObjectBase,IMyObject) private procedure AMethod; public class function CreateInstance: IMyObject; override; end; procedure Test; implementation { TMyDelegator } class function TMyDelegator.CreateInterfaced?( AMyObjectClass: TMyObjectBaseClass): IMyObjectClass; begin result := Create(AMyObjectClass); //hides Free method ... end; constructor TMyDelegator.Create(AMyObjectClass: TMyObjectBaseClass); begin inherited Create; FMyObjectClass := AMyObjectClass; //a MetaClassVariable end; function TMyDelegator.CreateInstance: IMyObject; begin result := FMyObjectClass.CreateInstance; end; { TFooObject } procedure TFooObject.AMethod; begin WriteLn(ClassName,'.AMethod'); end; class function TFooObject.CreateInstance: IMyObject; begin result := Create; end; { TBarObject } procedure TBarObject.AMethod; begin WriteLn(ClassName,'.AMethod'); end; class function TBarObject.CreateInstance: IMyObject; begin result := Create; end; /////////////////////////////////////////////////////////////////////////////// { Test } procedure Test; var a: IMyObjectClass; b: IMyObjectClass; x: IMyObject; y: IMyObject; begin a := TMyDelegator.CreateInterfaced?(TFooObject); b := TMyDelegator.CreateInterfaced?(TBarObject); x := a.CreateInstance; y := b.CreateInstance; x.AMethod; y.AMethod; end; end.