Dovremmo @ Sovrascrivere l'implementazione del metodo di un'interfaccia?


432

È necessario annotare un metodo che implementa un metodo di interfaccia @Override?

Il javadoc Overridedell'annotazione dice:

Indica che una dichiarazione di metodo ha lo scopo di sovrascrivere una dichiarazione di metodo in una superclasse. Se un metodo viene annotato con questo tipo di annotazione ma non sostituisce un metodo superclasse, i compilatori sono tenuti a generare un messaggio di errore.

Non penso che un'interfaccia sia tecnicamente una superclasse. O è?

Question Elaboration


5
caspita questa domanda potrebbe essere più breve, ma è la domanda di cui avevo bisogno. Grazie
Dan Rosenstark il

1
Non riesco a trovare il sostituto dell'articolo @Override (Oracle ha recentemente spostato i vecchi blog Sun). Sai come trovarlo?
Bill the Lizard,

4
Ormai dovremmo avere un'annotazione @Implement (s) (2015). Ciò renderà le cose chiare!
Alex,

3
ormai (2015) dovremmo usare @Override con Java 8?
Lorenzo Sciuto,

Risposte:


305

Dovresti usare @Override quando possibile. Impedisce che vengano fatti semplici errori. Esempio:

class C {
    @Override
    public boolean equals(SomeClass obj){
        // code ...
    }
}

Questo non viene compilato perché non esegue correttamente l'override public boolean equals(Object obj).

Lo stesso vale per i metodi che implementano un'interfaccia (solo 1.6 e versioni successive ) o sostituiscono il metodo di una classe Super.


150
Si noti che non è possibile aggiungere l'annotazione @Override a un metodo che implementa un'interfaccia in Java 5: genera un errore. È consentito in Java 6.
Bill Michell,

17
Um, no, non lo fa. Infatti, Eclipse inserisce automaticamente @Override durante la compilazione di metodi che implementano un'interfaccia.
jjnguy,

14
-1 fino a quando la risposta include una menzione del diverso comportamento da Java 1.5 a 1.6 per quanto riguarda l'implementazione di un metodo di interfaccia. Solo perché ho visto che è un aspetto confuso per le persone e merita davvero una menzione.
Grundlefleck,

2
Se eclipse si lamenta, aggiorna ur jdk a> 1.5 e modifica il livello di conformità del compilatore a 1.6 o 1.7. Per farlo, fai clic con il pulsante destro del mouse sul tuo progetto-> proprietà-> compilatore Java e selezionane uno superiore a 1.5.
Rose,

1
Qualcuno può pensare a un esempio che giustifica effettivamente la risposta (implementando interfacce anziché scavalcare i metodi di base)? Un grande vantaggio per me è che aiuta a stabilire le aspettative dei lettori su come e in che modo un particolare metodo potrebbe essere utilizzato.
Joe Lee-Moyet,

103

Credo che il comportamento di javac sia cambiato: con 1.5 ha proibito l'annotazione, con 1.6 non lo è. L'annotazione fornisce un ulteriore controllo in fase di compilazione, quindi se stai usando 1.6 ci proverei.


1
Qual è il controllo extra?
Michael Carman,

17
@Michael Puoi notare se qualche interfaccia è stata cancellata.
Sanghyun Lee,

68

Dovresti sempre annotare i metodi con @Overridese è disponibile.

In JDK 5 questo significa scavalcare i metodi delle superclassi, in JDK 6 e 7 significa scavalcare i metodi delle superclasse e implementare metodi di interfacce. Il motivo, come accennato in precedenza, è che consente al compilatore di rilevare errori laddove si ritiene che si stia sovrascrivendo (o implementando) un metodo, ma in realtà si sta definendo un nuovo metodo (firma diversa).

L' esempio equals(Object)vs. equals(YourObject)è un caso standard in questione, ma lo stesso argomento può essere fatto per le implementazioni dell'interfaccia.

Immagino che il motivo per cui non è obbligatorio annotare i metodi di implementazione delle interfacce sia che JDK 5 lo abbia contrassegnato come un errore di compilazione. Se JDK 6 rendesse obbligatoria questa annotazione, si romperebbe la compatibilità all'indietro.

Non sono un utente Eclipse, ma in altri IDE (IntelliJ), l' @Overrideannotazione viene aggiunta durante l'implementazione dei metodi di interfaccia se il progetto è impostato come progetto JDK 6+. Immagino che Eclipse sia simile.

Tuttavia, avrei preferito vedere un'annotazione diversa per questo utilizzo, forse @Implementsun'annotazione.



11

JDK 5.0 non ti consente di usare l' @Overrideannotazione se stai implementando il metodo dichiarato nell'interfaccia (il suo errore di compilazione), ma JDK 6.0 lo consente. Quindi potrebbe essere possibile configurare le preferenze del progetto in base alle proprie esigenze.


4

Se una classe concreta non sta scavalcando un metodo astratto, l'utilizzo @Overrideper l' implementazione è una questione aperta poiché il compilatore ti invariabilmente avviserà di eventuali metodi non implementati. In questi casi, si può argomentare che toglie la leggibilità: sono più cose da leggere sul codice e, in misura minore, vengono chiamate @Overridee non @Implement.


3

Sovrascrivere i propri metodi ereditati dalle proprie classi in genere non si romperà sui refactoring usando un ide. Ma se si ignora un metodo ereditato da una libreria, si consiglia di utilizzarlo. Se non lo fai, spesso non otterrai alcun errore in una successiva modifica della libreria, ma un bug ben nascosto.


3

Non è un problema con JDK. In Eclipse Helios, consente l'annotazione @Override per i metodi di interfaccia implementati, a prescindere da JDK 5 o 6. Come per Eclipse Galileo, l'annotazione @Override non è consentita, a prescindere da JDK 5 o 6.


2

Per me, spesso questo è l'unico motivo per cui un codice richiede la compilazione di Java 6. Non sono sicuro se ne valga la pena.


2

Leggendo il javadoc in java8, è possibile trovare quanto segue nella dichiarazione dell'interfaccia Override:

Se un metodo viene annotato con questo tipo di annotazione, i compilatori sono richiesti per generare un messaggio di errore, a meno che almeno una delle seguenti condizioni sia valida:

  • Il metodo sostituisce o implementa un metodo dichiarato in un supertipo.
  • Il metodo ha una firma che ha la precedenza equivalente a quella di qualsiasi metodo pubblico dichiarato in {@linkplain Object}.

Quindi, almeno in java8, dovresti usare @Override su un'implementazione di un metodo di interfaccia.


1

Eclipse stesso aggiungerà l' @Overrideannotazione quando gli viene detto di "generare metodi non implementati" durante la creazione di una classe che implementa un'interfaccia.


1

Il problema con l'inclusione di @Overrideè che ti fa pensare di aver dimenticato di chiamare il super.theOverridenMethod()metodo, il che è molto confuso . Questo dovrebbe essere cristallino. Forse Java dovrebbe offrire un @Interfaceda usare qui. Vabbè, l'ennesima peculiarità di Java a metà culo ...


3
Chiamare un super, quando non si implementa un'interfaccia, non è qualcosa che devi sempre o che vuoi fare. A volte, stai aggiungendo funzionalità, quindi la chiami. Altre volte, stai sostituendo la funzionalità, quindi non la chiami. Un autore dell'API dovrebbe documentare se si basa o meno sulla funzionalità interna e creare un contratto documentato su come estendere correttamente la classe.
lilbyrdie,

1

In Java 6 e versioni successive, è possibile utilizzare @Overrideper un metodo che implementa un'interfaccia.

Ma non credo abbia senso: l'override significa che hai un metodo nella superclasse e lo stai implementando nella sottoclasse.

Se stai implementando un'interfaccia, penso che dovremmo usare @Implemento qualcos'altro, ma non il @Override.


0

Per l'interfaccia, l'uso di @Override ha causato un errore di compilazione. Quindi, ho dovuto rimuoverlo.

Il messaggio di errore è andato " The method getAllProducts() of type InMemoryProductRepository must override a superclass method".

Ha anche letto " One quick fix available: Remove @Override annotation."

Era su Eclipse 4.6.3, JDK 1.8.0_144.


0

Se la classe che sta implementando interfaceè una abstractclasse, @Overrideè utile assicurarsi che l'implementazione sia per un interfacemetodo; senza la classe @Overridean si abstractcomporterebbe semplicemente bene anche se la firma del metodo di implementazione non corrisponde al metodo dichiarato in interface; il interfacemetodo non corrispondente rimarrebbe non implementato. Il documento Java citato da @Zhao

Il metodo sostituisce o implementa un metodo dichiarato in un supertipo

si riferisce chiaramente a una abstractsuper classe; un interfacenon può essere chiamato il supertipo. Quindi, @Overrideè ridondante e non sensato per l' interfaceimplementazione di metodi in classi concrete.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.