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

Reply via email to