Here's two simple classes, initially both have no keywords (virtual, overload, override, reintroduce):
TComputer = class(TObject)
public
constructor Create(Teapot: Integer);
end;
TCellPhone = class(TComputer)
public
constructor Create(Teapot: Integer; Handle: string);
end;
i will represent these above defintions as the slightly shorter:
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
And when constructing TCellPhone
there is only one constructor (int
, string
) - because the ancestor constructor has been hidden. i will indicate the visible constructors of TCellPhone
as:
Now for the question, the first 3 cases make sense, the 4th does not:
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
Teapot: Integer; Handle: string
This makes sense, the ancestor constructor is hidden because i've declared a new constructor.
TComputer = class(TObject)
constructor Create(Teapot: Integer); virtual;
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
Teapot: Integer; Handle: string
This makes sense, the ancestor constructor is hidden because i've declared a new constructor.
Note: Because the ancestor is virtual: Delphi will warn you that you're hiding the virtual ancestor (in the previous example of hiding a static constructor: nobody cares, so no warning). The warning can be suppressed (meaning "Yeah yeah yeah, i'm hiding a virtual constructor. i meant to do that.") by adding reintroduce:
TComputer = class(TObject) constructor Create(Teapot: Integer); virtual; TCellPhone = class(TComputer) constructor Create(Teapot: Integer; Handle: string); reintroduce;
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string); overload;
Teapot: Integer; Handle: string
Teapot: Integer
This makes sense, since the descendant constructor is an overload of the ancestor, so both are allowed to be present. The ancestor constructor is not being hidden.
This is the case that makes no sense:
TComputer = class(TObject)
constructor Create(Teapot: Integer); virtual;
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string); overload;
Teapot: Integer; Handle: string
Teapot: Integer
Method 'Create' hides virtual method of base type 'TComputer'
This makes little sense. Not only is the ancestor not hidden, the descendant is overloaded; it shouldn't even be complaining.
What gives?
The default constructor is a public no arguments constructor. To be more specific it has the same access level as the class, so public in a public class, private in a private class, etc.
Class constructors are package-private by default. Enum constructors are private by default. The only constructor that's public by default is the implicit, no-arguments one.
Abstract class cannot have a constructor. Explanation: No instance can be created of abstract class.
Delphi's documentation says:
If you overload a virtual method, use the reintroduce directive when you redeclare it in descendant classes. For example,
type T1 = class(TObject) procedure Test(I: Integer); overload; virtual; end; T2 = class(T1) procedure Test(S: string); reintroduce; overload; end;
Without the reintroduce directive, it still works, as you've noticed, but you'll get the warning.
Also, you are actually hiding TObject.Create, but it has nothing to do with the warning. If you think you might want access to TObject.Create also, do this:
type
TComputer = class(TObject)
constructor Create(Teapot: Integer); reintroduce; overload; virtual;
end;
type
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: String); reintroduce; overload;
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With