Должны ли мы @Override реализации метода интерфейса?

432

Следует ли аннотировать метод, реализующий интерфейсный метод @Override?

Javadoc в Overrideаннотации говорится:

Указывает, что объявление метода предназначено для переопределения объявления метода в суперклассе. Если метод аннотирован этим типом аннотации, но не переопределяет метод суперкласса, компиляторы должны генерировать сообщение об ошибке.

Я не думаю, что интерфейс технически суперкласс. Или это?

Question Elaboration

Бенно Рихтерс
источник
5
вау, этот вопрос может быть короче, но это вопрос, который мне нужен. Спасибо
Дэн Розенстарк
1
Я не могу найти замену статье @Override (Oracle недавно переместил старые блоги Sun). Ты знаешь как это найти?
Билл Ящерица
4
У нас должна быть аннотация @Implement (s) к настоящему времени (2015). Это прояснит ситуацию!
Алекс
3
К настоящему времени (2015) мы должны использовать @Override с Java 8?
Лоренцо Шиуто

Ответы:

305

Вы должны использовать @Override всякий раз, когда это возможно. Это предотвращает совершение простых ошибок. Пример:

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

Это не компилируется, потому что не корректно переопределяется public boolean equals(Object obj).

То же самое касается методов, которые реализуют интерфейс (только 1.6 и выше ) или переопределяют метод класса Super.

jjnguy
источник
150
Обратите внимание, что вы не можете добавить аннотацию @Override к методу, реализующему интерфейс в Java 5 - он генерирует ошибку. Это разрешено в Java 6.
Билл Мичелл
17
Хм, нет, это не так. Фактически, Eclipse автоматически вставляет @Override при заполнении методов, которые реализуют интерфейс.
jjnguy
14
-1, пока в ответ не будет включено упоминание о различном поведении от Java 1.5 до 1.6 в отношении реализации метода интерфейса. Просто потому, что я видел, что это сбивает с толку людей, и это действительно заслуживает упоминания.
Грундлефлек
2
Если eclipse жалуется, обновите ur jdk до> 1.5 и измените уровень соответствия компилятора до 1.6 или 1.7. Для этого щелкните правой кнопкой мыши на свой проект-> свойства-> Java-компилятор и выберите тот, который выше, чем 1,5.
Роза
1
Может кто-нибудь придумать пример, который действительно оправдывает ответ (реализация интерфейсов, а не переопределение базовых методов)? Большим плюсом для меня является то, что он помогает читателям рассчитывать на то, как и каким образом можно использовать тот или иной метод.
Джо Ли-Мойет
103

Я считаю, что поведение javac изменилось - с 1.5 это запретило аннотацию, с 1.6 - нет. Аннотация предоставляет дополнительную проверку во время компиляции, поэтому, если вы используете 1.6, я бы пошел на это.

Джон Скит
источник
1
Что такое дополнительная проверка?
Майкл Карман
17
@Michael Вы можете заметить, если какой-либо интерфейс был удален.
Санхьюн Ли
68

Вы должны всегда аннотировать методы, @Overrideесли они доступны.

В JDK 5 это означает переопределение методов суперклассов, в JDK 6 и 7 это означает переопределение методов суперклассов и реализацию методов интерфейсов. Причина, как упоминалось ранее, заключается в том, что он позволяет компилятору перехватывать ошибки, когда вы думаете, что переопределяете (или реализуете) метод, но на самом деле определяете новый метод (другую сигнатуру).

equals(Object)По сравнению с equals(YourObject)примером является стандартным примером, но тот же самый аргумент может быть сделан для реализаций интерфейса.

Я предполагаю, что причина, по которой нет необходимости комментировать методы реализации интерфейсов, заключается в том, что JDK 5 пометил это как ошибку компиляции. Если JDK 6 сделает эту аннотацию обязательной, это нарушит обратную совместимость.

Я не являюсь пользователем Eclipse, но в других IDE (IntelliJ) @Overrideаннотация добавляется только при реализации методов интерфейса, если проект задан как проект JDK 6+. Я предположил бы, что Затмение похоже.

Однако я бы предпочел увидеть другую аннотацию для этого использования, возможно, @Implementsаннотацию.

GKelly
источник
11

JDK 5.0 не позволяет вам использовать @Overrideаннотацию, если вы реализуете метод, объявленный в интерфейсе (его ошибка компиляции), но JDK 6.0 позволяет это. Так что, может быть, вы можете настроить предпочтения вашего проекта в соответствии с вашими требованиями.

Тихий воин
источник
4

Если конкретный класс не переопределяет абстрактный метод, использование @Overrideдля реализации является открытым вопросом, поскольку компилятор неизменно предупреждает вас о любых невыполненных методах. В этих случаях может быть выдвинут аргумент, что это снижает читабельность - в вашем коде читается больше вещей и, в меньшей степени, вызывается @Overrideи нет @Implement.

juanchito
источник
3

Переопределение ваших собственных методов, унаследованных от ваших собственных классов, обычно не нарушает рефакторинг с использованием ide. Но если вы переопределите метод, унаследованный от библиотеки, рекомендуется использовать его. Если вы этого не сделаете, вы часто получите не ошибку при более позднем изменении библиотеки, но хорошо скрытую ошибку.

Арне Бурмейстер
источник
3

Это не проблема с JDK. В Eclipse Helios он допускает аннотацию @Override для реализованных методов интерфейса, в зависимости от того, JDK 5 или 6. Что касается Eclipse Galileo, аннотация @Override недопустима, в зависимости от того, JDK 5 или 6.

lwpro2
источник
2

Для меня часто это единственная причина, по которой некоторый код требует компиляции Java 6. Не уверен, стоит ли это того.

Фабиан Стиг
источник
2

Читая javadoc в java8, вы можете найти следующее в объявлении переопределения интерфейса:

Если метод аннотирован этим аннотационным типом, компиляторы должны генерировать сообщение об ошибке, если не выполнено хотя бы одно из следующих условий:

  • Метод переопределяет или реализует метод, объявленный в супертипе.
  • Метод имеет сигнатуру, эквивалентную переопределению сигнатуры любого открытого метода, объявленного в {@linkplain Object}.

Поэтому, по крайней мере, в java8 вы должны использовать @Override для реализации метода интерфейса.

Чжао Пэнфэй
источник
1

Сам Eclipse добавит @Overrideаннотацию, когда вы скажете ему «генерировать нереализованные методы» во время создания класса, реализующего интерфейс.

savetheclocktower
источник
1

Проблема с включением @Overrideзаключается в том, что это заставляет вас думать, что вы забыли вызвать super.theOverridenMethod()метод, что очень запутанно . Это должно быть кристально ясно. Возможно, Java должен предложить @Interfaceиспользовать здесь. Ну да ладно, еще одна недоделанная особенность Java ...

spujia
источник
3
Вызов super, когда не реализован интерфейс, - это не то, что вам всегда нужно или нужно делать. Иногда вы добавляете функциональность - так вы это называете. В других случаях вы заменяете функциональность, поэтому не вызываете ее. Автор API должен задокументировать, использует ли он внутреннюю функциональность или нет, и создать документированный договор о том, как класс может быть должным образом расширен.
lilbyrdie
1

В Java 6 и более поздних версиях вы можете использовать @Overrideдля метода, реализующего интерфейс.

Но я не думаю, что это имеет смысл: переопределение означает, что у вас есть метод в суперклассе, и вы реализуете его в подклассе.

Если вы реализуете интерфейс, я думаю, что мы должны использовать @Implementили что-то еще, но не @Override.

ZhaoGang
источник
0

Для интерфейса использование @Override вызвало ошибку компиляции. Итак, я должен был удалить это.

Сообщение об ошибке отправлено " The method getAllProducts() of type InMemoryProductRepository must override a superclass method".

Это также читать " One quick fix available: Remove @Override annotation."

Это было на Eclipse 4.6.3, JDK 1.8.0_144.

Парк JongBum
источник
0

Если класс, который реализует, interfaceявляется abstractклассом, @Overrideполезно убедиться, что реализация предназначена для interfaceметода; без класса просто компилироваться даже если метод реализации подпись не соответствует методу объявлена в ; несоответствующий метод останется нереализованным. Документ Java, цитируемый @Zhao@Overrideabstractinterfaceinterface

Метод переопределяет или реализует метод, объявленный в супертипе.

явно относится к abstractсуперклассу; Ан interfaceнельзя назвать супертипом. Таким образом, @Overrideявляется избыточным и не имеет смысла для interfaceреализации методов в конкретных классах.

Мадху
источник