Inherited and not virtual/overridden procedures

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

Inherited and not virtual/overridden procedures

Bart-48
Hi,

I thought that if I had a subclass that inherited form a parentclass,
and both have a method with the same name (Bar), then the method of
the subclass hid the method of the parentclass, and you could not call
inherited Bar in the subclass.

More specifically I was under the impression that you could only call
inherited in an overriden method that was declared virtual in the
parentclass.

program test;

{$mode objfpc}{$H+}

uses
  SysUtils, Classes;

type
  TFoo = class
    procedure Bar;
  end;

  { TFooChild }

  TFooChild = class(TFoo)
    procedure Bar;
  end;

procedure TFoo.Bar;
begin
  writeln('TFoo.Bar');
end;

{ TFooChild }

procedure TFooChild.Bar;
begin
  inherited Bar;
  writeln('TFooChild.Bar');
end;


var
  FooChild: TFooChild;

begin
  FooChild := TFooChild.Create;
  FooChild.Bar;
  FooChild.Free;
end.

To my surprise this compiles without any warning or error.
It outputs:
C:\Users\Bart\LazarusProjecten\ConsoleProjecten>test
TFoo.Bar
TFooChild.Bar

Why then would I need virtual and override anymore?

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

Re: Inherited and not virtual/overridden procedures

Jonas Maebe-2

On 12 Jun 2013, at 00:12, Bart wrote:

> var
>  FooChild: TFooChild;
>
> begin
>  FooChild := TFooChild.Create;
>  FooChild.Bar;
>  FooChild.Free;
> end.
>
> To my surprise this compiles without any warning or error.
> It outputs:
> C:\Users\Bart\LazarusProjecten\ConsoleProjecten>test
> TFoo.Bar
> TFooChild.Bar
>
> Why then would I need virtual and override anymore?

So that it would still have the same behaviour if you changed the variable declaration to

var
  FooChild: TFoo;


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

Re: Inherited and not virtual/overridden procedures

Bart-48
On 6/12/13, Jonas Maebe <[hidden email]> wrote:

> So that it would still have the same behaviour if you changed the variable
> declaration to
>
> var
>   FooChild: TFoo;

If I change FooChild to TFoo (and instantiate with TFoo.Create) the
outut is always the same, wether or not I use virtual for TFoo.Bar and
wether or not I use override for TFooChild.Bar declarations.

In case of FooChild: TFoo it outputs
"TFoo.bar"

In case of FooChild: TFooChild it outputs
"TFoo.Bar"
"TFooChild.Bar"
in all scenario's I could think of.

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

Re: Inherited and not virtual/overridden procedures

Max Vlasov
In reply to this post by Bart-48

On Wed, Jun 12, 2013 at 2:12 AM, Bart <[hidden email]> wrote:

I thought that if I had a subclass that inherited form a parentclass,
and both have a method with the same name (Bar), then the method of
the subclass hid the method of the parentclass, and you could not call
inherited Bar in the subclass.


I see your point, but this question is more to the original designers of Delphi. I tried to look at real life examples from VCL (to find the roots of the "devil" :)) and there are cases when it's unavoidable

- Constructors call inherited no matter whether they're virtual or not. It just feels right to allow this.

- Message handlers call inherited. Technically they're similar to virtual methods so this is something that should have work even if calling inherited from non-virtual methods is prohibited. 

- Any method of ClassA(ClassB) can call inherited ClassB.SomeMethod if it's accidentally has the same name as SomeMethod of ClassA. 

- Most of the cases in the VCL is a kind of "type override: when one inherits from TCollection and want to add own Add with the new type of the item (to be sure no other types will be accepted). So in the body it's basically calling inherited Add with a typecast.

- An interesting case: TRegIniFile = class(TRegistry). There are many methods having the same name, but different parameters list. So, it's more semantic inheritance so if you replace the existing code working with registry, you just have to slightly change actual parameters of the methods called. 

Overall looking at all cases I think this keyword can be considered as a good universal prefix excluding the context of the existing class working with methods and properties. Even looking at the name it has more to do with INHERITance than polymorphism

Max

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

Re: Inherited and not virtual/overridden procedures

Jonas Maebe-2
In reply to this post by Bart-48

On 12 Jun 2013, at 13:33, Bart wrote:

On 6/12/13, Jonas Maebe <[hidden email]> wrote:

So that it would still have the same behaviour if you changed the variable
declaration to

var
 FooChild: TFoo;

If I change FooChild to TFoo (and instantiate with TFoo.Create) the

Now change the variable type to TFoo but keep instantiating it using TFooChild.Create (like I originally suggested). Having that work is the whole point of polymorphism and why virtual/override exist.


Jonas

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

Re: Inherited and not virtual/overridden procedures

Juha Manninen
In reply to this post by Max Vlasov
On Wed, Jun 12, 2013 at 2:39 PM, Max Vlasov <[hidden email]> wrote:
> Overall looking at all cases I think this keyword can be considered as a
> good universal prefix excluding the context of the existing class working
> with methods and properties. Even looking at the name it has more to do with
> INHERITance than polymorphism

Exactly. I don't see any problem with "inherited". It has nothing to
do with the "virtuality" of a method.

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

Re: Inherited and not virtual/overridden procedures

Bart-48
In reply to this post by Jonas Maebe-2
On 6/12/13, Jonas Maebe <[hidden email]> wrote:

> Now change the variable type to TFoo but keep instantiating it using
> TFooChild.Create (like I originally suggested). Having that work is
> the whole point of polymorphism and why virtual/override exist.

I didn't even know that was possible....

OK now I see the difference.
Not making them virtual/ovverride the shows only TFoo.Bar, whilst
making them virtual/override shows the TFooChild.Bar implementation.

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