我只是想问一个简单的问题 - 我有一个派生自TLabel的类如下:
TMyLabel = class (TLabel)
...
constructor Create(AOwner: TComponent); override;
end;
constructor TMyLabel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{ some code }
end;
现在,Delphi允许我使用和不使用覆盖编译这两个版本。你能解释一下这些差异是什么吗? 重写时,Create()
无法请求我自己的参数。感谢
编辑:我的意思是 - virtual
和非虚拟基本后代构造函数之间有什么区别?我总是可以通过inherited Create()
调用继承的构造函数,那有什么意义呢?
答案 0 :(得分:9)
虚拟构造函数允许对象的多态实例化。典型的例子是Delphi的.dfm流机制。
读取.dfm文件和实例化表单的代码在编译时不知道要使用哪些类。该决定被推迟到运行时,可以正确地进行,即读取.dfm文件时。此外,您可以获取.dfm文件机制来创建不属于VCL的自定义组件,因此此.dfm机制必须能够正确实例化不属于VCL的类。
TComponent
的构造函数声明如下:
constructor Create(AOwner: TComponent); virtual;
对于参与此机制的组件,它必须使用override
指令声明其构造函数。
该过程的另一个关键是类引用。例如
type
TComponentClass = class of TComponent;
在读取.dfm文件时创建组件的代码大致如下:
var
ComponentClass: TComponentClass;
Component, Owner: TComponent;
....
ComponentClass = FindComponentClass(ReadComponentClassName);
Component := ComponentClass.Create(Owner);
现在,如果机制没有使用虚拟构造函数,那么将被调用的构造函数将是TComponent.Create
。所以你的构造函数TMyLabel.Create
永远不会被调用。
这就是在从TComponent
派生时必须在构造函数中包含override指令的原因。
答案 1 :(得分:2)
好吧,如果我正确地记得Delphi(那是前一段时间,虽然这是好时光:))当构造函数被覆盖时,你将能够通过类引用调用它(参见this spec作为示例) 。