2010-11-18 11 views
6

quando inizio con Delphi ho letto che l'unico modo per evitare chiamate inutili del costruttore di parametri senza parametri è quello di lanciare un'eccezione o un'asserzione in esso. Quando ho usato la parola chiave reintroduzione la prima volta questa settimana, ho scoperto che sembra risolvere anche questo problema.Nascondere senza parametri Creare con reintroduzione?

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

Una chiamata a Test.Create mi dà l'errore del compilatore desiderato. Ci sono problemi con questo approccio?

risposta

4

Bene, problema semplice: se si reintroduce un metodo, si nasconderà il/i metodo/i genitore/i. Questo dovrebbe essere esattamente quello che vuoi, ma controllare questo codice:

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'); 

Questo vi dà due errori! Perché? Poiché entrambi i metodi DoSomething nel genitore sono ora nascosti! A volte, vuoi questo. Altre volte, non lo fai. E quando non lo fai, è necessario aggiungere i metodi mancanti alla classe figlia di nuovo, chiamando il metodo ereditato in questo modo:

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

Poi di nuovo, questo è quello che vuoi, giusto? Nascondere tutti i metodi genitore con lo stesso nome. Non dimenticare che puoi comunque chiamare i metodi ereditati.
Ricordati anche di collegare le interfacce alla classe genitore. La classe figlio continuerà a supportare l'interfaccia, ma chiamando i metodi attraverso l'interfaccia anziché l'oggetto risulterà in una chiamata al genitore, non al bambino!
Reintrodurre i metodi è una buona pratica nel caso in cui si desidera nascondere i metodi dal genitore. Tuttavia, nasconderà anche i metodi virtuali con lo stesso nome! Normalmente, sarebbe più semplice sovrascrivere i metodi virtuali, ma quando si modifica l'elenco dei parametri, l'uso di reintroduzione in realtà disabiliterebbe la classe genitore in circostanze normali al di fuori della classe. All'interno della classe, hai ancora accesso a loro, senza avvisi ...

+0

Tank you! Nascondere tutti i costruttori della classe base è esattamente quello che voglio. Nella maggior parte dei casi, una chiamata di un operatore di classe base non è sufficiente per inizializzare completamente l'oggetto concreto. – hansmaad

+0

Nota che reintrodurre semplicemente sopprime un avviso del compilatore. Il comportamento di runtime è lo stesso con o senza di esso. Stai attento se nascondi un distruttore. Se chiami 'TObject.Free' il distruttore figlio non verrà mai chiamato. –

+0

@Codeelegance, no. Reintroduzione renderà i metodi genitore non disponibili! Senza Reintrodurre, puoi comunque chiamare il metodo genitore senza alcun p [roblems. Con il reintrodurre, quei metodi genitore sono "andati", disponibili solo all'interno della classe figlio. –

1

Se si definisce un costruttore con un'altra firma, si nasconde effettivamente l'altro costruttore quindi l'avviso. La direttiva reintroduce dice al compilatore che sai cosa stai facendo in modo che non mostri l'avviso.

Quindi l'unico effetto è nascondere il costruttore precedente.

Se si desidera più varianti del costruttore, è possibile utilizzare la direttiva overload.

+0

Quando il compilatore ha iniziato ad avvertire di nascondere i metodi * non-virtuali *? Sicuramente un giorno dopo * Delphi 2005. Non ho mai visto un simile avvertimento. –

+0

Non completamente, btw. La definizione di qualsiasi metodo nel figlio esporrà ancora il metodo genitore al codice. Reintroduce nasconderà il metodo genitore dalla vista, assicurandoti che non puoi usarlo direttamente. (Anche se ancora lo chiamiamo come metodo ereditato o attraverso le interfacce.) –

Problemi correlati