[fpc-pascal] Understanding virtual methods
Martin
lazarus at mfriebe.de
Tue Aug 20 08:53:11 CEST 2013
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
More information about the fpc-pascal
mailing list