0

具有虚拟/动态的

// 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;

这些是一样的吗?看起来很混乱。

4

2 回答 2

5

Yes, there is a difference, but let's deal with the virtual keyword in more basic OOP terms first, yet still how it applies to Delphi methods.

When you declare a derived (child) class, and implement a method as "override", it means that you're overriding (surprise) the matching method of the base class.

This means that you can write code like this:

var child : TBaseClass;
begin
    child := TChildClass.Create; // note that it is stored in TBaseClass variable
    child.VirtualMethodDefinedInBaseClassThatHasBeenOverriddenInChildClass;

This will call the method in the child class, even if the variable is defined to be of the base class type. This is the whole purpose of virtual methods, you can access the object through a reference of a more general type, and still call methods that have been written for the particular type of object you're dealing with.

If you have a virtual method in the base class that you chose not to override in the child class, but instead reintroduce, you're effectively replacing it in some cases. Note that in most cases you need to tell the compiler that you really meant to do this, though I'm unsure about what Delphi requires here.

Basically, if your variable is of type TBaseClass, and you call a virtual method on it, that has been reintroduced in the TChildClass, it will still call the method in the base class.

However, if your variable is of type TChildClass, and you call that method on it, you will get the new method instead.

Now, for constructors, in Delphi, it is slightly different.

The point of virtual constructors is to be able to virtually construct objects, and to do that, Delphi also has "class types".

You can say this:

type TClassToUse = class of TBaseClass;
var cls : TClassToUse;
    obj : TBaseClass;
begin
    cls := TChildClass;
    obj := cls.Create;

(note that my Delphi knowledge is a bit rusty here, if anyone spots bugs or glaring problems in the above code, please let me know or just fix it)

Here we store a "class" in a variable, and then ask the class to please construct an object for us. This allows us to switch out which class to create, but we also need to declare the constructors we want to use virtual, otherwise we will have problems.

So in the above code, if you declared the constructor as virtual in TBaseClass, and then override it in TChildClass (which the code is actually using in cls), the overridden constructor is the one that will be used.

If, on the other hand, you don't declare the constructor as virtual, we're back to the base class constructor. Virtual basically means to figure out the right method to execute at runtime, whereas non-virtual will figure it out at compile time.

Reintroduction as described for normal methods above, also works this way.

However, virtual constructors are only used as virtual when used through a class type.

于 2013-06-29T14:26:48.687 回答
1

No, static and virtual methods are not the same thing.

And override is a case of virtual method.

http://en.wikipedia.org/wiki/Virtual_function

http://docwiki.embarcadero.com/RADStudio/XE4/en/Methods#Method_Binding

Constructors bring nothing special here - they conform to the same rules as other methods for the question

于 2013-06-29T14:27:18.247 回答