我有TParentObj = class(TComponent)
和TChildObj = class (TParentObj)
。另外我有一个TCustomObj = class of TParentObj
。
然后我想根据变量是什么来创建Type parent OR Type Child的对象。如果选择“child”,则应创建TChildObj
,依此类推。
在函数中我有一个var:obj : TCustomObj
。
然后我想做:
if oReturnType = TChildObj
obj := TChildObj.create
else if oReturnType = TParentObj
obj := TParentObj.create
oReturnType
已设置并在其他地方传递。
如果我使用'is'而不是'=',我会收到运算符不适用于此操作数类型的错误,如果我使用=,则会在TCustomObj
和TChildObj
之间出现不兼容的类型错误1}}和TParentObj
。
我已经搜索了很多,但还没有发现我做错了什么,并希望有人能够对此有所了解。
提前致谢。
答案 0 :(得分:3)
首先,您似乎错过了TClass
变量中最重要的一点:他们可以访问构造函数,也可以访问虚拟构造函数。
如果您将构造函数放在TParentObj
上并声明虚拟; ,然后让所有后代覆盖; 根据需要构造函数,那么{{声明为TClass
的变量将有权访问此虚拟构造函数,其行为与您期望虚拟方法的行为完全相同:
class of TParentObj
该技术广泛用于VCL;例如,它是Delphi表格流媒体系统的核心。 obj := oReturnType.Create();
//invoke the virtual constructor on the actual type of oReturnType
定义了一个签名为TComponent
的虚拟构造函数,每个需要新构造函数的自定义组件和控件都会覆盖此构造函数。这是一个非常有用的系统,如果你看一下它的工作方式,你很快就会对所涉及的技术有所了解。
但是对于实际问题,您在(AOwner: TComponent)
与TCustomObj
和TChildObj
之间出现了不兼容的类型错误,因为它们不是兼容类型。
TParentObj
和TChildObj
是对象类,TParentObj
是元类或类变量。 TCustomObj
变量表示对象,而TParentObj
(定义为TCustomObj
)表示类本身,而不是该类的对象。将class of TParentObj
声明为obj
(它将接受TParentObj
或其任何后代的对象实例)并且您将会很好。
答案 1 :(得分:2)
您可以使用classtype TCustomObj
来创建实例
function ObjFactory( AClass : TCustomObj ): TParentObj;
begin
Result := AClass.Create;
end;
procedure foo;
var
LObj : TParentObj;
begin
// instance of TParentObj
LObj := ObjFactory( TParentObj );
// or instance of TChildObj
LObj := ObjFactory( TChildObj );
end;