2014-12-09 6 views
6

ho difficoltà a capire il modo di interpretare java interfaccia eredità, ad esempio:Interfaccia di successione - cambiando i parametri del metodo

public interface Model { 
    Model getModel(); 
    void setModel(Model model); 
} 

public class BaseModel implements Model { 
    @Override 
    public BaseModel getModel() { return null; } // works 

    @Override 
    public void setModel(BaseModel model) {} // compilation error, it wants Model instead of BaseModel 
} 

Qualcuno potrebbe spiegare perché il primo metodo funziona, e la seconda non lo fa?

risposta

3

Per capire questo, è necessario chiedersi "Posso sostituire BaseModel per qualsiasi utilizzo dell'interfaccia Model"?

Quando si specializza il valore restituito, questo funziona correttamente. Anche se getModel() restituisce un BaseModel, può sempre essere assegnato a una variabile Model.

Model model = myModel.getModel(); 

Il contrario non è vero, però:

SomeOtherModel other = ...; 
myModel.setModel(other); // no problem 
myBaseModel.setModel(other); // other is not a BaseModel! 

se setModel dovesse accettare un parametro di BaseModel che ci si rompe la sua capacità di essere impostato con altre implementazioni di Model. Quindi, questo non è permesso.

3

È come funziona la funzione di sovrascrittura.

parametri
  1. La funzione devono essere esattamente identica.

  2. I tipi di ritorno possono essere diversi, ma devono essere correlati.

Quindi nel tuo caso, getModel va bene in quanto il tipo di ritorno (BaseModel) è legato alla Model, ma setModel non è valida in quanto i tipi di parametri sono dissimili.

5

tipo di ritorno il tuo primo metodo è covariant ed è autorizzato e il tipo di ritorno non è una parte del metodo di firma quindi il suo permesso

mentre il parametro a un metodo è una parte della firma e deve seguire rigorosamente la firma di interfaccia e quindi fallisce nel tuo caso.

Da quando hai annotato il tuo metodo con @Override, stai cercando di sovrascrivere il metodo, quindi il compilatore si lamenta dello stesso. Se si rimuove e implementa il metodo come da interfaccia oltre all'implementazione esistente, si sovraccaricherà il metodo.

2

Il nome del metodo e i tipi di parametro rendono una firma del metodo in Java e non il tipo restituito. Quando si esegue l'override di un metodo, la firma del metodo deve essere la stessa Se si modifica la firma, verrà sovraccaricata e non soggetta a override - per vederla se si rimuove l'annotazione @ Override funzionerà.