Delphi: ¿Cómo ocultar constructores ancestrales?
Actualizar: destripado la pregunta con un ejemplo más simple, que no es respondido por la respuesta originalmente aceptada
Dada la siguiente clase, y su antepasado:
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;
Ahora mismoTCellPhone
tiene 3 constructores visibles:
Que hago paraTCellPhone
para que el constructor ancestro (Teapot: string = ''
) no es visible, dejando solo los constructores declarados:
Nota: Por lo general, el simple acto deteniendo un constructor descendiente esconde al antepasado:
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); virtual;
end;
Copa: EnteroY si tuquerido para mantener tanto al constructor ancestro como al descendiente, marcaría al descendiente como unoverload
:
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); overload; virtual;
end;
Copa: EnteroTetera: cadena = ''En el código de ejemplo de esta pregunta, Delphi está confundiendo mioverload
palabras clave:
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); overload; virtual;
constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
pensar que:
quiero sobrecargar mis constructores con elantepasado,cuando realmente quiero sobrecargarlo con elhermano¿Cómo oculto el constructor ancestro?
Nota: Puede ser imposible ocultar el constructor ancestral, no virtual, utilizando el lenguaje Delphi como se define actualmente."Imposible" Es una respuesta válida.
Intento de respuesta (fallido)i intentó marcando los constructores descendientes conreintroduce
(recurriendo a mi modo de agregar palabras clave al azar hasta que funcione):
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); reintroduce; overload; virtual;
constructor Create(Cup: Integer; Teapot: string); reintroduce; overload; virtual;
end;
Pero eso no funcionó, los tres constructores aún son visibles. :(
Pregunta originalTengo un objeto que desciende de una clase que tiene constructores que no quiero ver:
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)
Nota: Este es un ejemplo hipotético. Como en el mundo real, los objetos ancestrales no se pueden cambiar sin romper el código existente.
Ahora cuando alguien está usandoTiPhone
ni siquiera quiero que puedanver el constructor deTEniac
:
iphone := TiPhone.Create(powerCord);
Peor aún: si llaman a ese constructor, extrañan completamente a mi constructor, y todo lo que se hace en el medio. Es bastante fácil llamar al constructor incorrecto, todos ellos son visibles en la finalización del código IDE y compilarán:
TiPhone.Create;
y obtienen un objeto completamente inválido.
podría cambiarTCellPhone
para lanzar una excepción en esos constructores:
TCellPhone.Create(PowerCord: TPowercord)
begin
raise Exception.Create('Don''t use.');
end;
Pero los desarrolladores no se darán cuenta de que están llamando al constructor equivocado hasta que el cliente encuentre el error un día y nos multe con miles de millones de dólares. De hecho, soymolesto para encontrar en todas partes, llamo al constructor equivocado, ¡pero no puedo entender cómo hacer que Delphi me lo diga!