Faut-il @Overrider l'implémentation d'une méthode d'interface?

432

Une méthode qui implémente une méthode d'interface doit-elle être annotée @Override?

Le javadoc de l' Overrideannotation dit:

Indique qu'une déclaration de méthode est destinée à remplacer une déclaration de méthode dans une superclasse. Si une méthode est annotée avec ce type d'annotation mais ne remplace pas une méthode de superclasse, les compilateurs sont tenus de générer un message d'erreur.

Je ne pense pas qu'une interface soit techniquement une superclasse. Ou est-ce?

Question Elaboration

Benno Richters
la source
5
wow cette question pourrait être plus courte, mais c'est la question dont j'avais besoin. Merci
Dan Rosenstark
1
Je ne trouve pas le remplacement de l'article @Override (Oracle a récemment déplacé les anciens blogs de Sun). Savez-vous comment le trouver?
Bill the Lizard
4
Nous devrions maintenant avoir une annotation @Implement (s) (2015). Cela clarifiera les choses!
Alex
3
maintenant (2015) devrions-nous utiliser @Override avec java 8?
Lorenzo Sciuto

Réponses:

305

Vous devez utiliser @Override dans la mesure du possible. Cela empêche les erreurs simples de se produire. Exemple:

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

Cela ne se compile pas car il ne remplace pas correctement public boolean equals(Object obj).

Il en ira de même pour les méthodes qui implémentent une interface ( 1.6 et supérieure uniquement ) ou remplacent la méthode d'une classe Super.

jjnguy
la source
150
Notez que vous ne pouvez pas ajouter l'annotation @Override à une méthode implémentant une interface dans Java 5 - cela génère une erreur. Il est autorisé en Java 6.
Bill Michell
17
Non, non. En fait, Eclipse insère automatiquement @Override lors du remplissage des méthodes qui implémentent une interface.
jjnguy
14
-1 jusqu'à ce que la réponse contienne une mention sur les différents comportements de Java 1.5 à 1.6 en ce qui concerne l'implémentation d'une méthode d'interface. Tout simplement parce que j'ai vu que c'était un aspect déroutant pour les gens et cela mérite vraiment une mention.
Grundlefleck
2
Si eclipse se plaint, mettez à niveau ur jdk vers> 1.5 et modifiez le niveau de conformité du compilateur à 1.6 ou 1.7. Pour ce faire, cliquez avec le bouton droit sur votre projet-> propriétés-> compilateur Java et sélectionnez celui qui est supérieur à 1,5.
Rose
1
Quelqu'un peut-il penser à un exemple qui justifie réellement la réponse (implémenter des interfaces plutôt que remplacer des méthodes de base)? Un grand avantage pour moi est que cela aide à définir les attentes des lecteurs sur la manière et la manière dont une méthode particulière pourrait être utilisée.
Joe Lee-Moyet
103

Je crois que le comportement de javac a changé - avec 1.5, il interdit l'annotation, avec 1.6, il ne le fait pas. L'annotation fournit une vérification supplémentaire au moment de la compilation, donc si vous utilisez 1.6 j'irais pour elle.

Jon Skeet
la source
1
Qu'est-ce que le chèque supplémentaire?
Michael Carman
17
@Michael Vous pouvez remarquer si une interface a été supprimée.
Sanghyun Lee
68

Vous devez toujours annoter les méthodes @Overridesi elles sont disponibles.

Dans JDK 5, cela signifie remplacer les méthodes des superclasses, dans JDK 6 et 7, cela signifie remplacer les méthodes des superclasses et implémenter des méthodes d'interfaces. La raison, comme mentionné précédemment, est qu'elle permet au compilateur de détecter les erreurs lorsque vous pensez que vous remplacez (ou implémentez) une méthode, mais que vous définissez en fait une nouvelle méthode (signature différente).

L' exemple equals(Object)vs. equals(YourObject)est un cas standard, mais le même argument peut être avancé pour les implémentations d'interface.

J'imagine que la raison pour laquelle il n'est pas obligatoire d'annoter les méthodes d'implémentation des interfaces est que JDK 5 a signalé cela comme une erreur de compilation. Si JDK 6 rendait cette annotation obligatoire, cela romprait la compatibilité descendante.

Je ne suis pas un utilisateur Eclipse, mais dans d'autres IDE (IntelliJ), l' @Overrideannotation n'est ajoutée lors de l'implémentation de méthodes d'interface que si le projet est défini comme un projet JDK 6+. J'imagine qu'Eclipse est similaire.

Cependant, j'aurais préféré voir une annotation différente pour cette utilisation, peut-être une @Implementsannotation.

GKelly
la source
11

JDK 5.0 ne vous permet pas d'utiliser l' @Overrideannotation si vous implémentez une méthode déclarée dans l'interface (son erreur de compilation), mais JDK 6.0 le permet. Il se peut donc que vous puissiez configurer les préférences de votre projet en fonction de vos besoins.

Guerrier silencieux
la source
4

Si une classe concrète ne remplace pas une méthode abstraite, l'utilisation @Overridepour l' implémentation est une question ouverte car le compilateur vous avertira invariablement de toute méthode non implémentée. Dans ces cas, un argument peut être avancé selon lequel cela nuit à la lisibilité - il y a plus de choses à lire sur votre code et, dans une moindre mesure, il est appelé @Overrideet non @Implement.

juanchito
la source
3

Remplacer vos propres méthodes héritées de vos propres classes ne se dérègle généralement pas lors des refactorings utilisant un ide. Mais si vous remplacez une méthode héritée d'une bibliothèque, il est recommandé de l'utiliser. Si vous ne le faites pas, vous n'obtiendrez souvent aucune erreur lors d'un changement de bibliothèque ultérieur, mais un bug bien caché.

Arne Burmeister
la source
3

Ce n'est pas un problème avec JDK. Dans Eclipse Helios, il permet l'annotation @Override pour les méthodes d'interface implémentées, quel que soit JDK 5 ou 6. Comme pour Eclipse Galileo, l'annotation @Override n'est pas autorisée, quel que soit JDK 5 ou 6.

lwpro2
la source
2

Pour moi, c'est souvent la seule raison pour laquelle certains codes nécessitent Java 6 pour être compilés. Je ne sais pas si ça vaut le coup.

Fabian Steeg
la source
2

En lisant le javadoc dans java8, vous pouvez trouver ce qui suit à la déclaration d'interface Override:

Si une méthode est annotée avec ce type d'annotation, les compilateurs sont requis pour générer un message d'erreur sauf si au moins une des conditions suivantes est remplie:

  • La méthode remplace ou implémente une méthode déclarée dans un supertype.
  • La méthode a une signature qui est équivalente à celle de n'importe quelle méthode publique déclarée dans {@linkplain Object}.

Donc, au moins dans java8, vous devez utiliser @Override sur une implémentation d'une méthode d'interface.

Zhao Pengfei
la source
1

Eclipse elle-même ajoutera l' @Overrideannotation lorsque vous lui direz de "générer des méthodes non implémentées" lors de la création d'une classe qui implémente une interface.

sauver la tour d'horloge
la source
1

Le problème avec l'inclusion de @Overridec'est qu'il vous fait penser que vous avez oublié d'appeler la super.theOverridenMethod()méthode, ce qui est très déroutant . Cela devrait être limpide. Peut-être que Java devrait proposer un @Interfaceà utiliser ici. Eh bien, encore une autre particularité Java à moitié âgée ...

spujia
la source
3
Appeler un super, quand vous n'implémentez pas d'interface, n'est pas quelque chose que vous devez ou voulez toujours faire. Parfois, vous ajoutez des fonctionnalités - vous l'appelez donc. D'autres fois, vous remplacez la fonctionnalité, vous ne l'appelez donc pas. Un auteur d'API doit documenter s'il s'appuie ou non sur des fonctionnalités internes et créer un contrat documenté sur la manière d'étendre correctement la classe.
lilbyrdie
1

Dans java 6 et versions ultérieures, vous pouvez utiliser @Overridepour une méthode implémentant une interface.

Mais, je ne pense pas que cela ait du sens: remplacer signifie que vous avez une méthode dans la super classe, et vous l'implémentez dans la sous-classe.

Si vous implémentez une interface, je pense que nous devrions utiliser @Implement ou autre chose, mais pas le @Override.

ZhaoGang
la source
0

Pour l'interface, l'utilisation de @Override a provoqué une erreur de compilation. J'ai donc dû l'enlever.

Le message d'erreur est allé "The method getAllProducts() of type InMemoryProductRepository must override a superclass method ".

Il disait également "One quick fix available: Remove @Override annotation. "

C'était sur Eclipse 4.6.3, JDK 1.8.0_144.

Park JongBum
la source
0

Si la classe qui implémente le interfaceest une abstractclasse, @Overrideest utile pour s'assurer que l'implémentation concerne une interfaceméthode; sans la classe @Overridean abstract, la compilation serait correcte même si la signature de la méthode d'implémentation ne correspond pas à la méthode déclarée dans le interface; la interfaceméthode inadéquate resterait non appliquée. Le document Java cité par @Zhao

La méthode remplace ou implémente une méthode déclarée dans un supertype

fait clairement référence à une abstractsuper classe; un interfacene peut pas être appelé le supertype. Donc, @Overrideest redondant et non sensible pour les interfaceimplémentations de méthodes dans les classes concrètes.

Madhu
la source