Должны ли мы @Использовать реализацию метода интерфейса?

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

javadoc аннотации Override говорит:

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

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

Разработка вопроса

Ответы

Ответ 1

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

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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

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

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

Ответ 10

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

Ответ 11

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

Ответ 12

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

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

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

Ответ 13

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

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

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

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

Ответ 14

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

The method getAllProducts() of type InMemoryProductRepository must override a superclass method сообщение об ошибке " 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.

Ответ 15

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

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

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