Jump to content
Jacek Laskowski

Class inheritance and hides method

Recommended Posts

I have two classes:
 

TFoo = class
   procedure Terminate(aNow: Boolean); virtual;
end;

TBar = class(TFoo)
   procedure Terminate();
end;

procedure TBar.Terminate();
begin
   inherited Terminate(True);
end;



but I am getting a warning when compiling:

 

[dcc32 Warning] W1010 Method 'Terminate' hides a virtual method of base type


How to correctly declare the Terminate () method?
 

I tried with overload, but it did not help.

Share this post


Link to post
54 minutes ago, Jacek Laskowski said:

I tried with overload, but it did not help.

http://docwiki.embarcadero.com/RADStudio/Rio/en/Methods_(Delphi)

 

Overload is used when you have methods with same name but different parameters.

 

Override is used when you have methods with same name and same parameters, but one is in parent class (marked as virtual or dynamic) and other is in child class and you want to override method functionality in child class.

Share this post


Link to post

Hmm..

 

I thing 'override' is wrong, 'reintroduce' have to use! The declaration is different.

  • Like 1

Share this post


Link to post

Of course, override generate other error:

 

[dcc32 Error] E2037 Declaration of 'Terminate' differs from previous declaration

 

Edited by Jacek Laskowski

Share this post


Link to post
11 minutes ago, Jacek Laskowski said:

Of course, override generate other error:

 


[dcc32 Error] E2037 Declaration of 'Terminate' differs from previous declaration

 

Implementing an override to a virtual method the signatures must match. Your error is not from using override, but from changing the signature.

  • Like 1

Share this post


Link to post
3 minutes ago, Bill Meyer said:

Implementing an override to a virtual method the signatures must match. Your error is not from using override, but from changing the signature.

I know where a warning message comes from.

I ask how to solve it correctly for the Terminate method without parameters.

Share this post


Link to post

Perhaps you should step back and ask why you want two distinct things to have the same name. That, rather than the banal compilation warning, is surely the real issue here. 

Edited by David Heffernan

Share this post


Link to post
2 hours ago, Jacek Laskowski said:

I have two classes:
 


TFoo = class
   procedure Terminate(aNow: Boolean); virtual;
end;

TBar = class(TFoo)
   procedure Terminate();
end;

procedure TBar.Terminate();
begin
   inherited Terminate(True);
end;

but I am getting a warning when compiling:
 


[dcc32 Warning] W1010 Method 'Terminate' hides a virtual method of base type

How to correctly declare the Terminate () method?

 

The classical way to handle this is to refactor TFoo like this:

 


TFoo = class(TObject)
strict protected
  procedure DoTerminate(aNow: Boolean); virtual;
public
  procedure Terminate; virtual;
end;

TBar = class(TObject)
public
  procedure Terminate; override;
end;

procedure TFoo.Terminate;
begin
  DoTerminate(false);
end;

procedure TBar.Terminate;
begin
  DoTerminate(true);
end;

 

 

Share this post


Link to post
20 minutes ago, David Heffernan said:

Perhaps you should step back and ask why toy want two distinct things to have the same name. That, rather than the banal compilation warning, is surely the real issue here.  

 

From the base class, TFoo inherits several different classes, just this one child class TBar should always pass True in this parameter.

Share this post


Link to post

 

9 minutes ago, PeterBelow said:

The classical way to handle this is to refactor TFoo like this:

 


TFoo = class(TObject)
strict protected
  procedure DoTerminate(aNow: Boolean); virtual;
public
  procedure Terminate; virtual;
end;

TBar = class(TObject)
public
  procedure Terminate; override;
end;

procedure TFoo.Terminate;
begin
  DoTerminate(false);
end;

procedure TBar.Terminate;
begin
  DoTerminate(true);
end;

 

Thanks, but what if another class inheriting from TFoo needs to be able to control the parameter from outside?

 

Share this post


Link to post
1 hour ago, Jacek Laskowski said:

I ask how to solve it correctly for the Terminate method without parameters.

If you want to use the same name with different parameters, you have to declare both methods as 'overload', or else declare the TBar method as 'reintroduce', which will still hide the TFoo method.

 

Otherwise, I would just rename the TBar method to something more meaningful:

TFoo = class
  procedure Terminate(aNow: Boolean); virtual;
end;

TBar = class(TFoo)
  procedure TerminateNow();
end;

procedure TBar.TerminateNow();
begin
  inherited Terminate(True);
end;

 

Share this post


Link to post
1 hour ago, Remy Lebeau said:

If you want to use the same name with different parameters, you have to declare both methods as 'overload', or else declare the TBar method as 'reintroduce', which will still hide the TFoo method.

You can as well combine both avoiding the hide effect:

  TBar = class(TFoo)
    procedure Terminate; reintroduce; overload;
  end;

 

  • Like 1

Share this post


Link to post
49 minutes ago, Uwe Raabe said:

You can as well combine both avoiding the hide effect:


  TBar = class(TFoo)
    procedure Terminate; reintroduce; overload;
  end;

 

That is actualy the documented way to do this. I wondered why it took so long before someone came up with it.

 

OP probably comes from C++, where directives like override, reintroduce or overload are not necessary. If the signature is different, it overloads and does not hide.

Edited by Rudy Velthuis

Share this post


Link to post
2 hours ago, Rudy Velthuis said:

OP probably comes from C++, where directives like override, reintroduce or overload are not necessary. If the signature is different, it overloads and does not hide.

Note that C++11 addes the 'override' keyword to the language, and its use is highly recommended to discover typos at compile-time.  If a derived class method wants to override a base class virtual method, an explicit 'override' allows the compiler to validate that the overriding method actually matches the signature of an available base virtual method, if not the compile fails.  Without the explicit 'override', a mistyped overriding method would be an overload instead, which can lead to logic errors not detectable until run-time.

  • Like 2

Share this post


Link to post
On 4/16/2019 at 11:37 PM, Remy Lebeau said:

Note that C++11 addes the 'override' keyword to the language, and its use is highly recommended to discover typos at compile-time.  If a derived class method wants to override a base class virtual method, an explicit 'override' allows the compiler to validate that the overriding method actually matches the signature of an available base virtual method, if not the compile fails.  Without the explicit 'override', a mistyped overriding method would be an overload instead, which can lead to logic errors not detectable until run-time.

I didn't know that, but it looks like it has the equivalent but opposite meaning of reintroduce in Delphi. Of course it is useful, in C++ too.

Share this post


Link to post
On 4/16/2019 at 8:32 PM, Rudy Velthuis said:

That is actualy the documented way to do this. I wondered why it took so long before someone came up with it.

 

OP probably comes from C++, where directives like override, reintroduce or overload are not necessary. If the signature is different, it overloads and does not hide.

Hmm..

 

I came with this some posts ago, but I think you didn't need overload when you use 'reintroduce'..

 

Share this post


Link to post
29 minutes ago, HolgerX said:

Hmm..

 

I came with this some posts ago, but I think you didn't need overload when you use 'reintroduce'..

 

If you use reintroduce, you hide the virtual implementation. But if you want to overload it, and leave the virtual method visible and accessible/inheritable too, you must use both reintroduce and overload, in the correct order. This is documented somewhere.

Edited by Rudy Velthuis

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×