Understanding virtual methods

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Understanding virtual methods

Xiangrong Fang
Hi All,

I am reading this document: http://www.freepascal.org/docs-html/ref/refsu29.html   and doing an experiment with the following code:

program project1;
{$mode objfpc}{$H+}
type
  TBase = class
    constructor Create; virtual;
  end;
  TDerived = class(TBase)
    constructor Create; override;
  end;

var
  c1, c2: TBase;
  c3: TDerived;

constructor TDerived.Create;
begin
  WriteLn('Entering TDerived.Create');
  inherited Create;
  WriteLn('Leaving TDerived.Create');
end;

constructor TBase.Create;
begin
  WriteLn('Entering TBase.Create');
  Writeln('Leaving TBase.Create');
end;

begin
  WriteLn('Creating a TBase and assigning to TBase variable...');
  c1 := TBase.Create;
  WriteLn('Creating a TDerived and assigning to TBase variable...');
  c2 := TDerived.Create;
  WriteLn('Creating a TDerived and assigning to TDerived variable...');
  c3 := TDerived.Create;
end.


The problem is, it makes NO DIFFERENCE at all in the following cases:

CASE 1:

TBase.Create;
TDerived.Create;

CASE 2:

TBase.Create; virtual;
TDerived.Create; virtual;

CASE 3:

TBase.Create; virtual;
TDerived.Create; override;

According to the document, "inherited" cannot be used in non-virtual methods, and it is wrong to use virtual in sub-class. But my test shows the contrary.   BTW, I am running Linux on 64bit platform.

Regards,
Shannon






_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

etrusco
On Mon, Aug 19, 2013 at 10:44 PM, Xiangrong Fang <[hidden email]> wrote:

> Hi All,
>
> I am reading this document:
> http://www.freepascal.org/docs-html/ref/refsu29.html   and doing an
> experiment with the following code:
>
> program project1;
> {$mode objfpc}{$H+}
> type
>   TBase = class
>     constructor Create; virtual;
>   end;
>   TDerived = class(TBase)
>     constructor Create; override;
>   end;
>
> var
>   c1, c2: TBase;
>   c3: TDerived;
>
> constructor TDerived.Create;
> begin
>   WriteLn('Entering TDerived.Create');
>   inherited Create;
>   WriteLn('Leaving TDerived.Create');
> end;
>
> constructor TBase.Create;
> begin
>   WriteLn('Entering TBase.Create');
>   Writeln('Leaving TBase.Create');
> end;
>
> begin
>   WriteLn('Creating a TBase and assigning to TBase variable...');
>   c1 := TBase.Create;
>   WriteLn('Creating a TDerived and assigning to TBase variable...');
>   c2 := TDerived.Create;
>   WriteLn('Creating a TDerived and assigning to TDerived variable...');
>   c3 := TDerived.Create;
> end.
>
>
> The problem is, it makes NO DIFFERENCE at all in the following cases:
>
> CASE 1:
>
> TBase.Create;
> TDerived.Create;
>
> CASE 2:
>
> TBase.Create; virtual;
> TDerived.Create; virtual;
>
> CASE 3:
>
> TBase.Create; virtual;
> TDerived.Create; override;
>
> According to the document, "inherited" cannot be used in non-virtual
> methods,

At least that's the result I would expect :)
I can confirm your findings; contrary to the documentation, a simple
test works correctly (the compiler prints no warnings or hints, both
method and constructor work correctly, calling either a non-virtual
from virtual, and virtual from non-virtual).


> and it is wrong to use virtual in sub-class.

It doesn't say that, it simply says that the redeclaration will not
override the base implementation (the different behavior for 'object'
is news to me!).

FWIW your test doesn't actually "exercise" inheritance, since virtual
constructors only make a difference when you call from a class
reference (similarly, you'll only see a difference in virtual methods
when calling from a base-typed variable).

Code>>>
var MyClass: TComponentClass = TDataModule;
begin
  MyClass.Create(nil);
<<<

will instantiate a TDataModule.

Code>>>
var MyControl: TControl;
begin
  MyControl := TButton.Create;
  MyControl.ExecuteDefaultAction;
<<<

will invoke TButton's implementation of ExecuteDefaultAction.

> But my test shows the  contrary.   BTW, I am running Linux on 64bit platform.
>
> Regards,
> Shannon

Best regards,
Flávio
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Xiangrong Fang
Hi Flavio,

Your findings confirmed mine, but not telling me why? It seems that the "virtual" keyword has no use at all!   To confirm this, I just removed the "inherited" call in TDerived, then re-run the program with or without "virtual/override", the result is exactly same, i.e. with c2 (declared as TBase), the following statements ALWAYS calls constructor of TDerived, NOT TBase:

c2 := TDerived.Create;
c2 := TBase(TDerived.Create);

This is not same as the description in: http://www.freepascal.org/docs-html/ref/refsu26.html

BTW, the above documents are talking about objects, but I am using classes, is there any difference here?

Shannon



2013/8/20 Flávio Etrusco <[hidden email]>
On Mon, Aug 19, 2013 at 10:44 PM, Xiangrong Fang <[hidden email]> wrote:
> Hi All,
>
> I am reading this document:
> http://www.freepascal.org/docs-html/ref/refsu29.html   and doing an
> experiment with the following code:
>
> program project1;
> {$mode objfpc}{$H+}
> type
>   TBase = class
>     constructor Create; virtual;
>   end;
>   TDerived = class(TBase)
>     constructor Create; override;
>   end;
>
> var
>   c1, c2: TBase;
>   c3: TDerived;
>
> constructor TDerived.Create;
> begin
>   WriteLn('Entering TDerived.Create');
>   inherited Create;
>   WriteLn('Leaving TDerived.Create');
> end;
>
> constructor TBase.Create;
> begin
>   WriteLn('Entering TBase.Create');
>   Writeln('Leaving TBase.Create');
> end;
>
> begin
>   WriteLn('Creating a TBase and assigning to TBase variable...');
>   c1 := TBase.Create;
>   WriteLn('Creating a TDerived and assigning to TBase variable...');
>   c2 := TDerived.Create;
>   WriteLn('Creating a TDerived and assigning to TDerived variable...');
>   c3 := TDerived.Create;
> end.
>
>
> The problem is, it makes NO DIFFERENCE at all in the following cases:
>
> CASE 1:
>
> TBase.Create;
> TDerived.Create;
>
> CASE 2:
>
> TBase.Create; virtual;
> TDerived.Create; virtual;
>
> CASE 3:
>
> TBase.Create; virtual;
> TDerived.Create; override;
>
> According to the document, "inherited" cannot be used in non-virtual
> methods,

At least that's the result I would expect :)
I can confirm your findings; contrary to the documentation, a simple
test works correctly (the compiler prints no warnings or hints, both
method and constructor work correctly, calling either a non-virtual
from virtual, and virtual from non-virtual).


> and it is wrong to use virtual in sub-class.

It doesn't say that, it simply says that the redeclaration will not
override the base implementation (the different behavior for 'object'
is news to me!).

FWIW your test doesn't actually "exercise" inheritance, since virtual
constructors only make a difference when you call from a class
reference (similarly, you'll only see a difference in virtual methods
when calling from a base-typed variable).

Code>>>
var MyClass: TComponentClass = TDataModule;
begin
  MyClass.Create(nil);
<<<

will instantiate a TDataModule.

Code>>>
var MyControl: TControl;
begin
  MyControl := TButton.Create;
  MyControl.ExecuteDefaultAction;
<<<

will invoke TButton's implementation of ExecuteDefaultAction.

> But my test shows the  contrary.   BTW, I am running Linux on 64bit platform.
>
> Regards,
> Shannon

Best regards,
Flávio
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Martin Frb
In reply to this post by Xiangrong Fang
On 20/08/2013 02:44, Xiangrong Fang wrote:
Hi All,

I am reading this document: http://www.freepascal.org/docs-html/ref/refsu29.html   and doing an experiment with the following code:

program project1;
{$mode objfpc}{$H+}
type
  TBase = class
    constructor Create; virtual;
  end;
  TDerived = class(TBase)
    constructor Create; override;
  end;


....
The problem is, it makes NO DIFFERENCE at all in the following cases:

CASE 1:

TBase.Create;
TDerived.Create;

CASE 2:

TBase.Create; virtual;
TDerived.Create; virtual;

CASE 3:

TBase.Create; virtual;
TDerived.Create; override;

According to the document, "inherited" cannot be used in non-virtual methods, and it is wrong to use virtual in sub-class. But my test shows the contrary.   BTW, I am running Linux on 64bit platform.



Using virtual with constructor makes a difference, if you use "class of" types

type
  TBaseClass = class of TBase;
  TDerivedClass = class of TDerived;

Var
  bc: TBaseClass;

begin
  bc:= TBase;
  bc.create;

  bc:= TDerived;
  bc.create;  // will call Tderived.create, but only in case 3
end;

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Xiangrong Fang
Thanks.  Do you mean that the rules I see in the document apply to NORMAL virtual methods, but not virtual constructors?

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.

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!

Could anyone explain these messes about:  virtual, override, overload, reintroduce??

Thanks a lot.
Shannon






2013/8/20 Martin <[hidden email]>
On 20/08/2013 02:44, Xiangrong Fang wrote:
Hi All,

I am reading this document: http://www.freepascal.org/docs-html/ref/refsu29.html   and doing an experiment with the following code:

program project1;
{$mode objfpc}{$H+}
type
  TBase = class
    constructor Create; virtual;
  end;
  TDerived = class(TBase)
    constructor Create; override;
  end;


....

The problem is, it makes NO DIFFERENCE at all in the following cases:

CASE 1:

TBase.Create;
TDerived.Create;

CASE 2:

TBase.Create; virtual;
TDerived.Create; virtual;

CASE 3:

TBase.Create; virtual;
TDerived.Create; override;

According to the document, "inherited" cannot be used in non-virtual methods, and it is wrong to use virtual in sub-class. But my test shows the contrary.   BTW, I am running Linux on 64bit platform.



Using virtual with constructor makes a difference, if you use "class of" types

type
  TBaseClass = class of TBase;
  TDerivedClass = class of TDerived;

Var
  bc: TBaseClass;

begin
  bc:= TBase;
  bc.create;

  bc:= TDerived;
  bc.create;  // will call Tderived.create, but only in case 3
end;

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Martin Frb
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  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Martin Frb
In reply to this post by Xiangrong Fang
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?

for all the rest, you should look for a tutorial.

it is to complex for the mailing list
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Antonio Fortuny
In reply to this post by Xiangrong Fang

Le 20/08/2013 07:34, Xiangrong Fang a écrit :
Hi Flavio,

Your findings confirmed mine, but not telling me why? It seems that the "virtual" keyword has no use at all!   To confirm this, I just removed the "inherited" call in TDerived, then re-run the program with or without "virtual/override", the result is exactly same, i.e. with c2 (declared as TBase), the following statements ALWAYS calls constructor of TDerived, NOT TBase:

c2 := TDerived.Create;
c2 := TBase(TDerived.Create);

This is not same as the description in: http://www.freepascal.org/docs-html/ref/refsu26.html

BTW, the above documents are talking about objects, but I am using classes, is there any difference here?
Yep: a class is a construct definig a collection of variables, properties and methods whilst an object is an instantiated class.

TMyClass = class(TSomething)            <<-------- this is a class
public
    constructor Create;
    blabla
end;

var
    obj: TMyClass ;        <<----------- this is a declared oblect which instantiates a class when created (see next line)
...
    Obj := TMyClass .Create;            <<----- now the class TMyClass exists thru the Obj object

In other words, a class is non existent whilst an object falls into the real world. A class describes, an object makes use of a class
A class is unique bet there can be lots of objects instantiating a class
These few words help to explain the basic difference even if some more technical explations couls be needed. AFAIK, all OOP languages use almost the same terminology

This is why class procedures and functions exist. But this is another story.

Antonio.

Shannon


--
Sita
                Software
Antonio Fortuny
Senior Software engineer

220, avenue de la Liberté
L-4602 Niederkorn
Tel.: +352 58 00 93 - 93
www.sitasoftware.lu
Your IT Partner

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

etrusco
In reply to this post by Xiangrong Fang
On Tue, Aug 20, 2013 at 2:34 AM, Xiangrong Fang <[hidden email]> wrote:
> Hi Flavio,
>
> Your findings confirmed mine, but not telling me why?

I don't know why, maybe FPC used to be more strict about the use of
inherited, or the docs are simply wrong.


> It seems that the "virtual" keyword has no use at all!

It does, and the documentation is correct in this respect.


>  To confirm this, I just removed the
> "inherited" call in TDerived, then re-run the program with or without
> "virtual/override", the result is exactly same, i.e. with c2 (declared as
> TBase), the following statements ALWAYS calls constructor of TDerived, NOT
> TBase:
>
> c2 := TDerived.Create;
> c2 := TBase(TDerived.Create);

As I said - or tried to say ;) - in the other post, there won't be a
difference when invoking the constructor on a "class literal"
directly.
The second line will generate the exact same code as the first one;
you're instantiating a TDerived instance then "upcasting" it to TBase.


> This is not same as the description in:
> http://www.freepascal.org/docs-html/ref/refsu26.html

Note this page is about methods and you're using constructors in your example.
I would recommend you first do your tests on method declarations, and
later learn about class references (i.e. "class of" declarations) and
constructors.


> BTW, the above documents are talking about objects, but I am using classes,
> is there any difference here?
>
> Shannon

AFAIU per the first page you sent, you can't shadow/reintroduce a
virtual method in an object; when you redeclare a virtual method it
overrides the base one.

-Flávio
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Sven Barth-2
In reply to this post by Antonio Fortuny

Am 20.08.2013 09:36 schrieb "Antonio Fortuny" <[hidden email]>:
>
>
> Le 20/08/2013 07:34, Xiangrong Fang a écrit :
>>
>> Hi Flavio,
>>
>> Your findings confirmed mine, but not telling me why? It seems that the "virtual" keyword has no use at all!   To confirm this, I just removed the "inherited" call in TDerived, then re-run the program with or without "virtual/override", the result is exactly same, i.e. with c2 (declared as TBase), the following statements ALWAYS calls constructor of TDerived, NOT TBase:
>>
>> c2 := TDerived.Create;
>> c2 := TBase(TDerived.Create);
>>
>> This is not same as the description in: http://www.freepascal.org/docs-html/ref/refsu26.html
>>
>> BTW, the above documents are talking about objects, but I am using classes, is there any difference here?
>
> Yep: a class is a construct definig a collection of variables, properties and methods whilst an object is an instantiated class.

You are aware that the link mentioned by Xiangrong Fang points to a part of the manual about Turbo Pascal style objects which are different in a different sense to Delphi style objects/classes?

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Antonio Fortuny

Le 20/08/2013 14:34, Sven Barth a écrit :

>>
>> This is not same as the description in: http://www.freepascal.org/docs-html/ref/refsu26.html
>>
>> BTW, the above documents are talking about objects, but I am using classes, is there any difference here?
>
> Yep: a class is a construct definig a collection of variables, properties and methods whilst an object is an instantiated class.

You are aware that the link mentioned by Xiangrong Fang points to a part of the manual about Turbo Pascal style objects which are different in a different sense to Delphi style objects/classes?

Yes, but as he posts a question in a FPC list I imagine he is looking for some general information. He looks not to be in trouble. Lest's wait and see

Regards,
Sven



_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

--
Sita
                Software
Antonio Fortuny
Senior Software engineer

220, avenue de la Liberté
L-4602 Niederkorn
Tel.: +352 58 00 93 - 93
www.sitasoftware.lu
Your IT Partner

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Sven Barth-2

Am 20.08.2013 14:39 schrieb "Antonio Fortuny" <[hidden email]>:
>
>
> Le 20/08/2013 14:34, Sven Barth a écrit :
>>
>> >>
>> >> This is not same as the description in: http://www.freepascal.org/docs-html/ref/refsu26.html
>> >>
>> >> BTW, the above documents are talking about objects, but I am using classes, is there any difference here?
>> >
>> > Yep: a class is a construct definig a collection of variables, properties and methods whilst an object is an instantiated class.
>>
>> You are aware that the link mentioned by Xiangrong Fang points to a part of the manual about Turbo Pascal style objects which are different in a different sense to Delphi style objects/classes?
>
> Yes, but as he posts a question in a FPC list I imagine he is looking for some general information. He looks not to be in trouble. Lest's wait and see

That has nothing to do with FPC list or not. Xiangrong Fang asked about two different language features here and you told him something about a completely different difference related to one of the two language features.
Your answer is simply not an answer to his question.

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Xiangrong Fang
Hi Sven,

Thank you for comment :)   I am interested in a high level description of how these concepts (virtual / reintroduce / overloading) differs and how they affect programming, and I am currently not running into trouble, just try to get a better understanding of the language.

I'll explain my question / confusions:

1)  I didn't notice that my question are related to "modes" of fpc, i.e. turbo-pascal/delphi/objfpc.    If they are different, I would like to know more details, and I am more interested in objfpc mode, not those "compatibility" modes.

2) I know override / overload are completely different thing, I am not trying to compare apple with orange.   Also, I am clear about the definition of virtual methods and their purpose.  What I need help is to explain the observations I found with my demo app (which is a bit different than I expected).  For example, why we need "reintroduce" while "overload" does the same job and better (it makes both methods available)?

Thanks,
Shannon






2013/8/20 Sven Barth <[hidden email]>

Am 20.08.2013 14:39 schrieb "Antonio Fortuny" <[hidden email]>:


>
>
> Le 20/08/2013 14:34, Sven Barth a écrit :
>>
>> >>
>> >> This is not same as the description in: http://www.freepascal.org/docs-html/ref/refsu26.html
>> >>
>> >> BTW, the above documents are talking about objects, but I am using classes, is there any difference here?
>> >
>> > Yep: a class is a construct definig a collection of variables, properties and methods whilst an object is an instantiated class.
>>
>> You are aware that the link mentioned by Xiangrong Fang points to a part of the manual about Turbo Pascal style objects which are different in a different sense to Delphi style objects/classes?
>
> Yes, but as he posts a question in a FPC list I imagine he is looking for some general information. He looks not to be in trouble. Lest's wait and see

That has nothing to do with FPC list or not. Xiangrong Fang asked about two different language features here and you told him something about a completely different difference related to one of the two language features.
Your answer is simply not an answer to his question.

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Understanding virtual methods

Sven Barth-2
On 20.08.2013 15:39, Xiangrong Fang wrote:
> 1)  I didn't notice that my question are related to "modes" of fpc, i.e.
> turbo-pascal/delphi/objfpc.    If they are different, I would like to
> know more details, and I am more interested in objfpc mode, not those
> "compatibility" modes.

It has nothing to do with the modes besides the fact that the language
construct "object" is available in all modes except macpas and that the
language construct "class" is available in modes ObjFPC, Delphi,
DelphiUnicode, MacPas (there also available as "object" for
compatibility) and through the modeswitch "class". But objects and
classes behave consistently to matter which mode is used.

> 2) I know override / overload are completely different thing, I am not
> trying to compare apple with orange.   Also, I am clear about the
> definition of virtual methods and their purpose.  What I need help is to
> explain the observations I found with my demo app (which is a bit
> different than I expected).  For example, why we need "reintroduce"
> while "overload" does the same job and better (it makes both methods
> available)?

"reintroduce" allows you to "break" the chain of virtual methods to add
a new parameter and to hide the old method (for example, because calling
the inherited method in your child class breaks things or whatever).
"overload" just allows you to define two (or more) methods with the same
name that have different parameter lists (result type of functions does
not matter!). In mode ObjFPC this is normally done automatically while
in mode Delphi you need to explicitely declare them as "overload".

I hope this cleared things up a bit.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal