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

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

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

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

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

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

16 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

Я бы использовал это при каждой возможности. См. Когда вы используете аннотацию @Override в Java и почему?

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

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

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

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

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

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

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

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

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

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

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

Это может быть слишком поздний ответ. Но я надеюсь, что этот пример поможет кому-то понять, почему это так важно (для такого сценария)

      public interface Restaurant(){
    public boolean getBill();
    public BigDecimal payAmount();
}

public interface Food() extends Restaurant{
    public boolean haveSomeFood();
    public boolean drinkWater();
}

public class Hungry() implements Food{
    public boolean haveSomeFood(){}
    public boolean drinkWater(){}
    public boolean getBill(){}
    public BigDecimal payAmount(){}
}

В приведенном выше примере, если я Hungry, я могу получить от Restaurant. Но если я взял реализацию ресторана, мне не нужно получать счет и не нужно платить сумму!!!!

Как?

  • Интерфейс Foodимеет ключевое слово extends Restaurant- значит класс Hungry тоже реализован из интерфейса Restaurant.
  • Методы, фактически переопределяемые из интерфейса , не имеют ключевого слова
  • Итак, если я удалю ключевое слово extends Restaurant (или, скажем, если я удалю интерфейс Restaurant, он не покажет никакой ошибки.

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

Примечание . Когда вы реализуете интерфейс, вы можете не знать, расширяется ли этот интерфейс на другой интерфейс или может быть расширен, или наследование может быть удалено. Поэтому всегда лучше использовать @overrideключевое слово

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

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

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

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

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

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

Для интерфейса использование @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.

Другие вопросы по тегам