虚拟/动态
// declare in Child Class
constructor Create; virtual;
constructor TChildClass.Create;
begin
inherited;
end;
有覆盖的那个。
// declare in Child Class
constructor Create; override;
constructor TChildClass.Create;
begin
inherited;
end;
没有任何东西
// declare in Child Class
constructor Create;
constructor TChildClass.Create;
begin
inherited;
end;
这些是一回事吗?看起来很混乱。
答案 0 :(得分:5)
是的,存在差异,但我们首先使用更基本的OOP术语来处理virtual
关键字,但它仍然适用于Delphi方法。
当您声明派生(子)类并将方法实现为“覆盖”时,这意味着您将覆盖(惊讶)基类的匹配方法。
这意味着您可以编写如下代码:
var child : TBaseClass;
begin
child := TChildClass.Create; // note that it is stored in TBaseClass variable
child.VirtualMethodDefinedInBaseClassThatHasBeenOverriddenInChildClass;
这将调用子类中的方法,即使该变量被定义为基类类型也是如此。这是虚方法的全部目的,您可以通过更通用的类型的引用来访问对象,并且仍然调用为您正在处理的特定类型的对象编写的方法。
如果你在基类中有一个虚拟方法,你选择不在子类中重写,而是重新引入,那么在某些情况下你会有效地替换它。请注意,在大多数情况下,您需要告诉编译器您确实打算这样做,尽管我不确定Delphi在这里需要什么。
基本上,如果您的变量是TBaseClass类型,并且您在其上调用了一个虚拟方法,那么它已经在TChildClass中重新引入,它仍然会在基类中调用该方法。
但是,如果您的变量属于TChildClass类型,并且您在其上调用该方法,则会获得新方法。
现在,对于构造函数,在Delphi中,它略有不同。
虚拟构造函数的要点是能够虚拟构造对象,为此,Delphi也有“类类型”。
你可以这样说:
type TClassToUse = class of TBaseClass;
var cls : TClassToUse;
obj : TBaseClass;
begin
cls := TChildClass;
obj := cls.Create;
(请注意,我的Delphi知识在这里有点生疏,如果有人发现上述代码中的错误或明显问题,请告诉我或者只是解决它)
这里我们在变量中存储一个“类”,然后让类请为我们构造一个对象。这允许我们切换出要创建的类,但是我们还需要声明我们想要使用虚拟的构造函数,否则我们会遇到问题。
所以在上面的代码中,如果你在TBaseClass中将构造函数声明为虚拟,然后在TChildClass中覆盖它(代码实际上在cls
中使用),则被覆盖的构造函数将被使用
另一方面,如果您没有将构造函数声明为虚拟,我们将返回基类构造函数。 Virtual基本上意味着找出在运行时执行的正确方法,而非虚拟方法将在编译时计算出来。
如上述常规方法所述的重新引入,也是这样的。
但是,虚拟构造函数仅在通过类类型使用时用作虚拟。
答案 1 :(得分:1)
不,静态和虚拟方法不是一回事。
而override
是virtual
方法的一种情况。
http://en.wikipedia.org/wiki/Virtual_function
http://docwiki.embarcadero.com/RADStudio/XE4/en/Methods#Method_Binding
构造函数在这里没有什么特别之处 - 它们符合与问题的其他方法相同的规则