On 20/08/2013 07:32, Xiangrong Fang wrote:
Thanks. Do you mean that the rules I see in the document apply to
NORMAL virtual methods, but not virtual constructors?
They apply to constructors too. But...
A virtual/overridden method is looked up based on the class used in code
TDerived.create; // the class given is TDerived
var
b: TBase;
b := TDerived.create; // the class given still is TDerived
the assignment has nothing do to, what you class the method is called on.
b.Foo(); // Foo il looked up based on TBase
if b contains an instance of TDerived, then it depends on Foo being virtual.
Also, I have a related question: it seems that to override methods
in ancestor it is required that the method has same signature, however
reintroduce will not have such limitations. Example:
constructor TBase.Create; virtual;
... ...
constructor TDerived.Create(AParam: TParamType); override
The above code won't compile until I change the override keyword to
"reintroduce". Because the compiler complains that there is no
Create() with the same signature in the base class.
Try to understand it on normal methods first. That is easier.
(Technically it is the same for constructors, but you need a very
abstract view, to realize this)
TBase = class
procedure Foo; virtual;
...
TDerived = class
procedure Foo; override;
var
b: TBase;
d : TDerevied
WITHOUT virtual/overide
b := TDerived.Create
b.Foo; // will ca Foo declared on TBAse (because "b" is declared as TBase)
d.Foo // always call Foo from TDerived, because d can NOT contain a
TBase anyway
WITH virtual/overide
b := TDerived.Create
b.Foo; // will call Foo declared on TDerived (because "b" is CONTAINS a
TDerived)
ASSUMING (impossible) you wanted
procedure Foo(a: String); override;
b.Foo; // should call Foo declared on either TFoo or TDerived, depending
what was assigned to b
but if a TDerived was assigned, then it would break, because there is no
argument.
so this is impossible
However, if I use reintroduce, according to the document, the compiler
will make the Create method STATIC and hide the create method in the
base class, in another word, it is then invalid to call
TDerived.Create; (without param). What is the mechanism here??
Also, if I do not use override or reintroduce, instead, put an
"overload" there, it will make BOTH version of the constructor
visible, AND the "inherited" keyword also works well!
"reintroduce" is just a way to get rid of the warning, indicating that
you did not accidental use the same name as in the base class
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal