2016-04-06 21 views
9

Da Effective Java 2 ° edizione, punto 17:Quando si pianifica l'ereditarietà, i costruttori possono chiamare metodi sovrascrivibili?

Per ogni metodo pubblico o protetto o il costruttore, la documentazione devono indicare quali metodi override del metodo o il costruttore richiama

Più tardi nello stesso articolo:

I costruttori non devono invocare metodi sovrascrivibili, direttamente o indirettamente.

Queste due affermazioni non sono contraddittorie o mi manca qualcosa?

+0

È possibile leggerlo in un senso che non è contraddittorio: può essere vacuamente vero che la documentazione di un costruttore indica tutti i metodi sovrascrivibili invocati, se non sono stati richiamati metodi sovrascrivibili. Ma sospetto che non sia lo spirito in cui è stato scritto, né quello che stai dicendo :) –

+0

Non proprio, dovresti documentare quali membri inviabili invochi, solo così qualcuno può ignorarli, e in seguito non può dire > "hey, ma non mi hai mai informato di ignorare questo o quello non avrebbe > effetti collaterali" A parte questo, ci saranno sempre persone che cambiano i metodi nelle loro classi (overriden), che potrebbero infrangere il tuo codice, quindi è meglio non farlo mai. – Stultuske

risposta

1

L'invocazione di metodi sovrascrivibili durante la costruzione è consentita - non c'è nulla di illegale in questo.

Invocare metodi overridable durante la costruzione non è consigliabile - E 'generalmente mal consigliato di richiamare i metodi overridable durante la costruzione perché questo può causare gli oggetti incompleti per essere esposti e limita la prevedibilità del sistema.

public class A { 

    final int a; 

    public A() { 
     a = method(); 
    } 

    protected int method() { 
     return 42; 
    } 

    @Override 
    public String toString() { 
     return "A{" + "a=" + a + '}'; 
    } 

} 

public class B extends A { 

    @Override 
    protected int method() { 
     System.out.println("this=" + this); 
     return 96; 
    } 

} 

public void test() { 
    System.out.println("B = " + new B()); 
} 

Si noti che la prima citazione si riferisce solo alla documentazione, non al codice. Vorrei suggerire l'unico problema è l'uso di deve quando dovrebbe sarebbe probabilmente più appropriato.

Problemi correlati