Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-06

Inherited and not virtual/overridden procedures

7 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bart

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

Jonas Maebe
to Bart
Bart wrote 16 lines
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

Bart
to Jonas Maebe
Jonas Maebe wrote 5 lines
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

Max Vlasov
to Bart: I thought that if I had a subclass that inherited form a parentclass, and both have a…
Bart wrote 7 lines
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

Jonas Maebe
to Bart: If I change FooChild to TFoo (and instantiate with TFoo.Create) the outut is always the…
Bart wrote 10 lines
On 6/12/13, Jonas Maebe 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

Juha Manninen
to Max Vlasov: I see your point, but this question is more to the original designers of Delphi. I tried…
Max Vlasov 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

Bart
to Jonas Maebe: Now change the variable type to TFoo but keep instantiating it using TFooChild.Create…
Jonas Maebe 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