21
votes

Consider the hypothetical object hierarchy, starting with:

TFruit = class(TObject)
public
    constructor Create(Color: TColor); virtual;
end;

and its descendant:

TApple = class(TFruit)
public
    constructor Create(); overload; virtual;
    constructor Create(Color: TColor); overload; override; //deprecated. Calls other constructor - maintaining the virtual constructor chain
end;

The idea here is that I've overridden the virtual constructor of the base class, with an overload that also happens to be virtual.

Delphi complains:

Method 'Create' hides virtual method of base type 'TFruit'

Except it doesn't hide it - it's right there!

  • I overrode the virtual method in the ancestor, and
  • I overloaded it with another version

What's the deal?

2
I get "Method 'Create' hides virtual method of base type 'TFruit'"; are you really getting "base type 'TApple'"?user743382
@RBA Not exactly, the warning is incorrect in this case, although you can use reintroduce; to avoid it.user743382
This is specific to Delphi 5?EMBarbosa
@EMBarbosa No, but when using an older version, you might wonder if such a thing is specific to that version. OP is just being informative.NGLN
@NGLN Yup. So I think it doesn't need delphi-5 tag?EMBarbosa

2 Answers

29
votes

Two solutions:

type
  TFruit = class(TObject)
  public
    constructor Create(Color: TColor); virtual;
  end;

  TApple = class(TFruit)
  public
    constructor Create(); reintroduce; overload;
    constructor Create(Color: TColor); overload; override;
  end;

Or:

type
  TFruit = class(TObject)
  public
    constructor Create; overload; virtual; abstract;
    constructor Create(Color: TColor); overload; virtual;
  end;

  TApple = class(TFruit)
  public
    constructor Create(); override;
    constructor Create(Color: TColor); override; 
  end;
5
votes

This appears to be a "which came first" sort of issue. (It appears NGLN found a solution.)

There's another solution, also. You can use a default parameter:

interface

type
  TFruit=class(TObject)
  public
    constructor Create(Color: TColor); virtual;
  end;

  TApple=class(TFruit)
  public
    constructor Create(Color: TColor = clRed); override;
  end;

implementation

{ TFruit }

constructor TFruit.Create(Color: TColor);
begin
  inherited Create;
end;

{ TApple }

constructor TApple.Create(Color: TColor);
begin
  inherited;
end;

// Test code
var
  AppleOne, AppleTwo: TApple;
begin
  AppleOne := TApple.Create;
  AppleTwo := TApple.Create(clGreen);
end;