Une méthode qui implémente une méthode d'interface doit-elle être annotée avec @Override
?
Le javadoc de l'annotation Override
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 doivent générer un message d'erreur.
Je ne pense pas qu'une interface est techniquement une super-classe. Ou est-ce?
Vous devez utiliser @Override autant que possible. Cela évite des erreurs simples. Exemple:
class C {
@Override
public boolean equals(SomeClass obj){
// code ...
}
}
Cela ne compile pas car il ne remplace pas correctement public boolean equals(Object obj)
.
Il en va de même pour les méthodes qui implémentent une interface (1.6 et les versions supérieures uniquement) ou substituent la méthode d'une classe Super.
Je crois que le comportement de javac a changé - avec 1.5, il interdisait l'annotation, avec 1.6, il n'en avait pas. L'annotation fournit une vérification supplémentaire au moment de la compilation, donc si vous utilisez la version 1.6, je l'essaierai.
Vous devez toujours annoter les méthodes avec @Override
si elles sont disponibles.
Dans JDK 5, cela signifie des méthodes de substitution des superclasses, dans JDK 6 et 7, des méthodes de substitution des superclasses et la mise en œuvre de méthodes d'interface. La raison, comme mentionné précédemment, est que cela permet au compilateur d'attraper les erreurs lorsque vous pensez que vous substituez (ou implémentez) une méthode, mais définissez en fait une nouvelle méthode (signature différente).
L'exemple equals(Object)
contre equals(YourObject)
est un exemple typique, mais le même argument peut être avancé pour les implémentations d'interface.
J'imagine que la raison pour laquelle l'annotation des méthodes d'implémentation des interfaces n'est pas obligatoire est que JDK 5 l'a signalé comme une erreur de compilation. Si JDK 6 rend cette annotation obligatoire, la compatibilité avec les versions antérieures sera rompue.
Je ne suis pas un utilisateur Eclipse, mais dans d'autres IDE (IntelliJ), l'annotation @Override
est uniquement ajoutée lors de l'implémentation de méthodes d'interface si le projet est défini en tant que projet JDK 6+. J'imagine que Eclipse est similaire.
Cependant, j'aurais préféré voir une annotation différente pour cet usage, peut-être une annotation @Implements
.
Je l'utiliserais à chaque occasion. Voir Quand utilisez-vous l'annotation @Override de Java et pourquoi?
JDK 5.0 ne vous permet pas d'utiliser l'annotation @Override
si vous implémentez une méthode déclarée dans l'interface (son erreur de compilation), mais JDK 6.0 le permet. Ainsi, vous pourrez peut-être configurer vos préférences de projet en fonction de vos besoins.
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 le kit JDK 5 ou 6. Comme pour Eclipse Galileo, l'annotation @Override n'est pas autorisée, quel que soit le kit JDK 5 ou 6.
Remplacer vos propres méthodes héritées de vos propres classes ne résoudra généralement pas les refactorisations à l'aide d'un ide. Mais si vous substituez 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 bogue bien caché.
Pour moi, c'est souvent la seule raison pour laquelle du code nécessite la compilation de Java 6. Pas sûr que ça en vaille la peine.
Si un concret classe n'est pas écrasant une méthode abstraite, utiliser @Override
pour implémentation est une question ouverte, car le compilateur vous préviendra systématiquement de toute méthode non implémentée. Dans ces cas, on peut argumenter que cela nuit à la lisibilité: il s'agit de choses à lire sur votre code et, dans une moindre mesure, il s'appelle @Override
et non @Implement
.
Eclipse lui-même ajoutera l'annotation @Override
lorsque vous lui direz de "générer des méthodes non implémentées" lors de la création d'une classe implémentant une interface.
En lisant le javadoc dans Java8, vous pouvez trouver ce qui suit dans la déclaration de l'interface prioritaire:
Si une méthode est annotée avec cette annotation, les compilateurs doivent générer un message d'erreur, sauf si l'une au moins des conditions suivantes est remplie:
Donc, au moins en Java8, vous devriez utiliser @Override sur une implémentation d'une méthode d'interface.
Dans Java 6 et les versions ultérieures, vous pouvez utiliser @Override
pour une méthode implémentant une interface.
Mais, je ne pense pas que cela ait du sens: override signifie que vous avez une méthode dans la super classe et que vous la mettez en œuvre dans la sous-classe.
Si vous implémentez une interface, je pense que nous devrions utiliser @Implement
ou autre chose, mais pas le @Override
.
Le problème avec l'inclusion du @Override
est que cela vous fait penser que vous avez oublié d'appeler la méthode super.theOverridenMethod()
, qui est très déroutant . Cela devrait être limpide. Peut-être que Java devrait offrir un @Interface
à utiliser ici. Eh bien, encore une autre particularité de Java à moitié foutue ...
Pour l'interface, l'utilisation de @Override a provoqué une erreur de compilation. Donc, je devais l'enlever.
Le message d'erreur est allé "The method getAllProducts() of type InMemoryProductRepository must override a superclass method
".
Il a également lu "One quick fix available: Remove @Override annotation.
"
C'était sur Eclipse 4.6.3, JDK 1.8.0_144.
Si la classe qui implémente interface
est une classe abstract
, @Override
est utile pour garantir que l'implémentation concerne une méthode interface
; sans @Override
, une classe abstract
compilerait simplement bien même si la signature de la méthode d'implémentation ne correspond pas à la méthode déclarée dans interface
; la méthode incompatible interface
resterait comme non implémenté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 classe abstract
super; une interface
ne peut pas être appelée le supertype . Donc, @Override
est redondant et non raisonnable pour les implémentations de méthodes interface
dans des classes concrètes.