Update: gutted the question with a simpler example, that isn't answered by the originally accepted answer
Given the following class, and its ancestor:
TComputer = class(TObject)
public
constructor Create(Teapot: string='');
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); overload; virtual;
constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
Right now TCellPhone
has 3 constructors visible:
- Cup: Integer
- Cup: Integer; Teapot: string
- Teapot: string = ''
What do i do to TCellPhone
so that the ancestor constructor (Teapot: string = ''
) is not visible, leaving only the declared constructors:
- Cup: Integer
- Cup: Integer; Teapot: string
Note: Usually the simple act of having a descendant constructor hides the ancestor:
TCellPhone = class(TComputer) public constructor Create(Cup: Integer); virtual; end;
- Cup: Integer
And if you wanted to keep both the ancestor constructor and the descendant, you would mark the descendant as an
overload
:TCellPhone = class(TComputer) public constructor Create(Cup: Integer); overload; virtual; end;
- Cup: Integer
- Teapot: string = ''
In this question's example code, Delphi is mistaking my overload
keywords:
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); overload; virtual;
constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
to think that:
- i want to overload my constructors with the ancestor,
- when really i want to overload it with the sibling
How do i hide the ancestor constructor?
Note: It might be impossible to hide the ancestor, non-virtual, constructor using the Delphi language as it is currently defined. "Not possible" is a valid answer.
Attempted Answer (failed)
i tried marking the descendant constructors with reintroduce
(falling back to my mode of randomly adding keywords until it works):
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); reintroduce; overload; virtual;
constructor Create(Cup: Integer; Teapot: string); reintroduce; overload; virtual;
end;
But that didn't work, all three constructors are still visible. :(
Original Question
i have an object that descends from a class that has constructors don't want to see:
TEniac = class(TObject)
constructor Create(PowerCord: TPowerCord=nil); //calls inherited Create
TComputer = class(TEniac) ...
constructor Create(PowerCord: TPowerCord=nil); //calls inherited Create(nil)
TCellPhone = class(TComputer)
constructor Create(sim: TSimChip; UnlockCode: Integer); //calls inherited Create(nil)
TiPhone = class(TCellPhone)
constructor Create(sim: TSimChip); //calls inherited Create(sim, 0)
Note: This is a hypothetical example. As in the real world, the ancestor objects cannot be changed without breaking existing code.
Now when someone's using TiPhone
i don't want them even being able to see the constructor from TEniac
:
iphone := TiPhone.Create(powerCord);
Worse still: if they call that constructor, they completely miss my constructor, and everything done in between. It's pretty easy to call the wrong constructor, all of them are visible in the IDE code-completion, and will compile:
TiPhone.Create;
and they get a completely invalid object.
i could change TCellPhone
to throw an exception in those constructors:
TCellPhone.Create(PowerCord: TPowercord)
begin
raise Exception.Create('Don''t use.');
end;
But developers won't realize they're calling the wrong constructor until the customer finds the error one day and fines us bazillions of dollars. In fact, i'm trying to find everywhere i call the wrong constructor - but i can't figure out how to make Delphi tell me!