Нужно ли добавлять аннотацию @Override
при реализации интерфейса (не переопределять абстрактный класс)?
И чем достигается аннотация @Override
?
Нужно ли добавлять аннотацию @Override
при реализации интерфейса (не переопределять абстрактный класс)?
И чем достигается аннотация @Override
?
В Java 5 вы не должны добавлять @Override
при реализации метода, унаследованного от интерфейса, в Java 6, вы должны (или вы получите предупреждение компилятора).
@Override
утверждает, что метод предназначен для того, чтобы переопределить что-то, и заставит компилятор уведомить вас, если это не так или нет, например, потому что метод, который вы переопределяете, был переименован.
Он разбивает ваш компилятор, если вы говорите, что переопределяете что-то, когда вы этого не сделали.
Если вы не поместите тег @Override, но, согласно компилятору, вы ничего не переопределили, у вас есть тихая ошибка, о которой вы не знаете. С тегом @Override вы знаете об этом, и вы знаете об этом сейчас, а не позже.
Вы НИКОГДА НЕОБХОДИМА разместить аннотацию @Override. Но я бы рекомендовал делать это каждый раз.
Аннотация @Override
сообщает компилятору, что элемент предназначен для переопределения элемента, объявленного в суперклассе.
Это не требуется, но он сгенерирует ошибку компиляции, если этот метод на самом деле неправильно переопределяет метод в суперклассе.
@override
в основном заставляет компилятор проверить, что вы действительно переопределяете существующий метод базового класса, а не просто (случайно), создавая новый метод.
Хорошей практикой всегда пользоваться @Override
, так как она может помочь вам упредить некоторые коварные ошибки. Это также улучшает четкость кода. Например, посмотрите пример, приведенный в "Эффективной Java", глава 6, пункт № 36:
// Can you spot the bug? - Page 176
package org.effectivejava.examples.chapter06.item36;
import java.util.HashSet;
import java.util.Set;
public class Bigram {
private final char first;
private final char second;
public Bigram(char first, char second) {
this.first = first;
this.second = second;
}
public boolean equals(Bigram b) {
return b.first == first && b.second == second;
}
public int hashCode() {
return 31 * first + second;
}
public static void main(String[] args) {
Set<Bigram> s = new HashSet<Bigram>();
for (int i = 0; i < 10; i++)
for (char ch = 'a'; ch <= 'z'; ch++)
s.add(new Bigram(ch, ch));
System.out.println(s.size());
}
}
Этот метод может выглядеть хорошо на первый взгляд, но на самом деле он очень сломан! Программист не выполнил контракт equals(Object o)
, вместо этого выполнив equals(Bigram b)
, который не будет вызываться при выполнении действий, зависящих от equals()
; то есть вставки экземпляров Bigram
в Map
. Таким образом, это вызовет запутанное, тонкое неправильное поведение, которое будет трудно отследить, тогда как если бы программист только использовал @Override
, компилятор немедленно предупредил их о проблеме.
НЕТ, Java не обязывает вас помещать аннотацию @Override при реализации интерфейса. Вы можете переопределить методы, объявленные в интерфейсе, как обычно. Но хорошей практикой является использование аннотации @Override при переопределении методов интерфейса или любого родительского класса, включая абстрактный класс. Зачем? Потому что это помогает нам/компилятору идентифицировать любую проблему в переопределении метода в самой компиляции.
Например: http://java-dive.blogspot.in/
class Ball{
public void bounce(){
}
}
//////////////////////Override without @Override/////////////////////////////
public class FootBall{
public void bounce(String s){
}
}
//this will compile however new FootBall().bounce(); will call parent method.
//////////////////////Override with @Override/////////////////////////////
public class FootBall{
@Override
public void bounce(String s){
}
}
//This will not compile as the parent class doent have any method with signature bounce(String s)