Чи слід @Override впровадження методу інтерфейсу?


432

Чи слід анотувати метод, що реалізує метод інтерфейсу @Override?

Javadoc в Overrideанотації сказано:

Вказує на те, що оголошення методу призначене для заміщення оголошення методу в надкласовому класі. Якщо метод анотований цим типом анотацій, але не замінює метод надкласового класу, компілятори потрібні для створення повідомлення про помилку.

Я не думаю, що інтерфейс технічно є суперкласом. Або це?

Question Elaboration


5
Нічого це питання може бути коротшим, але це питання, яке мені потрібно. Дякую
Дан Розенстарк,

1
Я не можу знайти заміну для статті @Override (Oracle недавно перемістив старі блоги Sun). Ви знаєте, як його знайти?
Білл Ящірка

4
На сьогодні ми повинні мати анотацію @Implement (s) (2015). Це зробить все зрозумілим!
Олексій

3
до цього моменту (2015 р.) ми повинні використовувати @Override з java 8?
Lorenzo Sciuto

Відповіді:


305

Ви повинні використовувати @Override, коли це можливо. Це заважає робити прості помилки. Приклад:

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

Це не компілюється, оскільки не належним чином перекриває public boolean equals(Object obj).

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


150
Зауважте, що ви не можете додати анотацію @Override до методу, що реалізує інтерфейс в Java 5 - це генерує помилку. Це дозволено на Java 6.
Білл Мішелл

17
Гм, ні, це не так. Фактично, Eclipse автоматично вставляє @Override при заповненні методів, що реалізують інтерфейс.
jjnguy

14
-1, поки відповідь не включить згадку про різну поведінку від Java 1.5 до 1.6 стосовно реалізації методу інтерфейсу. Просто тому, що я бачив, що це заплутаний аспект для людей, і він дійсно заслуговує на згадку.
Grundlefleck

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 Ви можете помітити, чи видалений будь-який інтерфейс.
Sanghyun Lee

68

Ви завжди повинні коментувати методи, @Overrideякщо вони доступні.

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

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

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

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

Однак я хотів би побачити іншу примітку для цього використання, можливо, @Implementsпримітку.



11

JDK 5.0 не дозволяє використовувати @Overrideанотацію, якщо ви реалізуєте метод, оголошений в інтерфейсі (його помилка компіляції), але JDK 6.0 дозволяє. Тож, можливо, ви можете налаштувати свої переваги проекту відповідно до своїх вимог.


4

Якщо конкретний клас не перекриває абстрактний метод, використання @Overrideдля реалізації є відкритим питанням, оскільки компілятор незмінно попередить вас про будь-які безреалізовані методи. У цих випадках можна зробити аргумент, що це шкодить читабельності - це більше речей, які слід прочитати у вашому коді, і, меншою мірою, його називають, @Overrideа не @Implement.


3

Перевизначення власних методів, успадкованих від ваших власних класів, як правило, не порушується на рефактори, використовуючи ідею. Але якщо ви перекриєте метод, успадкований з бібліотеки, рекомендується використовувати його. Якщо ви цього не зробите, ви часто не отримаєте помилки при подальшій зміні бібліотеки, а добре приховану помилку.


3

Це не проблема з JDK. У програмі Eclipse Helios він дозволяє анотацію @Override для реалізованих методів інтерфейсу, залежно від JDK 5 або 6. Що стосується Eclipse Galileo, анотація @Override заборонена, залежно від того, який би був JDK 5 або 6.


2

Для мене часто це є єдиною причиною, чому якийсь код вимагає компілювати Java 6. Не впевнений, чи варто того.


2

Читаючи javadoc в java8, ви можете знайти наступне в декларації інтерфейсу Override:

Якщо метод анотований до цього типу анотацій, для генерування повідомлення про помилку потрібні компілятори, якщо не виконується принаймні одне з наступних умов:

  • Метод переосмислює або реалізує метод, оголошений у супертипі.
  • Метод має підпис, що еквівалентно підписі будь-якого публічного методу, оголошеного в {@linkplain Object}.

Отже, принаймні в java8, ви повинні використовувати @Override для реалізації методу інтерфейсу.


1

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


1

Проблема в тому числі @Overrideполягає в тому, що вона змушує думати, що ви забули викликати super.theOverridenMethod()метод, що дуже заплутано . Це має бути кристально чистим. Можливо, Java повинна запропонувати @Interfaceвикористовувати тут. Ну добре, ще одна напівозначна особливість Java ...


3
Виклик супер, якщо не реалізувати інтерфейс, - це не те, що вам завжди потрібно або потрібно робити. Іноді ви додаєте функціональність - так ви це називаєте. В іншому випадку ви замінюєте функціональність, тому не називаєте її. Автор API повинен задокументувати, покладається він на внутрішню функціональність чи ні, і створити документований контракт про те, як можна правильно розширити клас.
lilbyrdie

1

У версіях java 6 та новіших версіях ви можете використовувати @Overrideметод, що реалізує інтерфейс.

Але я не думаю, що це має сенс: переосмислення означає, що ви маєте метод у суперкласі, і ви реалізуєте його в підкласі.

Якщо ви реалізуєте інтерфейс, я думаю, ми повинні використовувати @Implementчи щось інше, але не той @Override.


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.


0

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

Метод переосмислює або реалізує метод, оголошений у супертипі

чітко відноситься до abstractсупер класу; а interfaceне можна назвати супертипом. Отже, він @Overrideє надмірним та не розумним для interfaceреалізації методів у конкретних класах.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.