2010-11-18 19 views
6

cuando comienzo con Delphi, leí que la única forma de evitar llamadas inútiles al constructor Create sin parámetros es lanzar una excepción o aserción en él. Cuando utilicé la palabra clave reintroduce la primera vez esta semana, descubrí que parece resolver también este problema.Ocultar sin parámetros Crear con reintroduce?

Test = class 
private 
    n_ : Integer; 
public 
    constructor Create(n : Integer); reintroduce; 
end; 

Una llamada a Test.Create me da el error de compilación deseado. ¿Hay algún problema con este enfoque?

Respuesta

4

Bien, problema simple: si reintroduce un método, ocultará los métodos principales. Esto debería ser exactamente lo que quiere, pero comprueba este código:

type 
    TClassParent = class 
    public 
    procedure DoSomething; overload; 
    procedure DoSomething(Something: Integer); overload; 
    end; 
    TClassChild = class(TClassParent) 
    public 
    procedure DoSomething(SomethingElse: string); reintroduce; 
    end; 
var 
    Child: TClassChild; 
begin 
    Child := TClassChild.Create; 
    Child.DoSomething; 
    Child.DoSomething(1024); 
    Child.DoSomething('Something'); 

Esto le da dos errores! ¿Por qué? ¡Porque ambos métodos DoSomething en el padre están ahora ocultos! A veces, quieres esto. Otras veces, no lo haces. Y cuando no lo hace, es necesario añadir esos métodos que faltan a la clase de niño otra vez, llamando al método heredado así:

procedure TClassChild.DoSomething(SomethingElse: string); 
begin 
    inherited DoSomething(SomethingElse); 
end; 

otra parte, esto es lo que quieres, ¿verdad? Ocultando todos los métodos parentales con el mismo nombre. Pero no olvide que aún puede llamar a los métodos heredados.
También tenga en cuenta cuando vincula interfaces a la clase principal. La clase secundaria todavía será compatible con la interfaz, pero llamar a los métodos a través de la interfaz en lugar de un objeto dará como resultado una llamada al padre, ¡no al niño!
Reintroducir métodos es una buena práctica en caso de que quiera ocultar métodos del padre. ¡También ocultará los métodos virtuales con el mismo nombre! Normalmente, sería mejor omitir los métodos virtuales, pero al cambiar la lista de parámetros, el uso de la reintroducción realmente deshabilitaría la clase principal en circunstancias normales fuera de la clase. Dentro de la clase, todavía tiene acceso a ellos, sin advertencias ...

+0

Tank you! Ocultar todos los constructores de la clase base es exactamente lo que quiero. En la mayoría de los casos, una llamada de un ctor de clase base es insuficiente para inicializar completamente el objeto concreto. – hansmaad

+0

Tenga en cuenta que reintroducir simplemente suprime una advertencia del compilador. El comportamiento del tiempo de ejecución es el mismo con o sin él. Tenga cuidado si oculta un destructor. Si llama a 'TObject.Free', nunca se llamará al destructor hijo. –

+0

@Codeelegance, no. Reintroduce también hará que los métodos principales no estén disponibles. Sin Reintroduce, aún puede llamar al método principal sin ningún problema. Con la reintroducción, los métodos principales se "eliminaron", disponibles solo dentro de la clase secundaria. –

1

Si define un constructor con otra firma, efectivamente oculta el otro constructor y, por lo tanto, la advertencia. La directiva reintroduce le dice al compilador que usted sabe lo que está haciendo para que no muestre la advertencia.

De modo que el único efecto es que oculta el constructor anterior.

Si quiere múltiples variantes del constructor, puede usar la directiva de sobrecarga.

+0

¿Cuándo comenzó el compilador a advertir sobre la ocultación de métodos * no virtuales *? Definitivamente en algún momento * después de * Delphi 2005. Nunca había visto tal advertencia. –

+0

No completamente, por cierto. Definir cualquier método en el niño seguirá exponiendo el método principal a su código. Reintroduce ocultará el método principal de la vista, asegurándose de que no pueda usarlo directamente. (Aunque todavía lo llamamos método heredado o a través de interfaces.) –

Cuestiones relacionadas