Czy powinniśmy @Override implementację metody interfejsu?

432

Czy metoda, która implementuje metodę interfejsu, powinna być opatrzona adnotacjami @Override?

Javadoc z Overridedopiskiem mówi:

Wskazuje, że deklaracja metody ma zastąpić deklarację metody w nadklasie. Jeśli metoda jest opatrzona adnotacjami za pomocą tego typu adnotacji, ale nie zastępuje metody nadklasy, kompilatory są wymagane do wygenerowania komunikatu o błędzie.

Nie sądzę, aby interfejs był technicznie nadklasą. Albo to jest?

Question Elaboration

Benno Richters
źródło
5
wow, to pytanie może być krótsze, ale to pytanie było mi potrzebne. Dzięki
Dan Rosenstark,
1
Nie mogę znaleźć zamiennika artykułu @Override (Oracle przeniosła ostatnio stare blogi Sun). Czy wiesz jak to znaleźć?
Bill the Lizard
4
Do tej pory powinniśmy mieć adnotację @Implement (s) (2015). To wszystko wyjaśni!
Alex
3
do tej pory (2015) powinniśmy używać @Override z java 8?
Lorenzo Sciuto,

Odpowiedzi:

305

W miarę możliwości należy używać @Override. Zapobiega popełnianiu prostych błędów. Przykład:

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

Nie kompiluje się, ponieważ nie zastępuje poprawnie public boolean equals(Object obj).

To samo dotyczy metod, które implementują interfejs (tylko 1.6 i wyżej ) lub zastępują metodę klasy Super.

jjnguy
źródło
150
Pamiętaj, że nie można dodać adnotacji @Override do metody implementującej interfejs w Javie 5 - generuje błąd. Jest to dozwolone w Javie 6.
Bill Michell
17
Nie, nie ma. W rzeczywistości Eclipse automatycznie wstawia @Override podczas wypełniania metod implementujących interfejs.
jjnguy
14
-1, dopóki odpowiedź nie zawiera wzmianki o różnych zachowaniach od Java 1.5 do 1.6 w odniesieniu do implementacji metody interfejsu. Tylko dlatego, że widziałem, że jest to mylący aspekt dla ludzi i naprawdę zasługuje na wzmiankę.
Grundlefleck,
2
Jeśli Eclipse narzeka, zaktualizuj swój jdk do> 1.5 i zmień poziom zgodności kompilatora na 1.6 lub 1.7. Aby to zrobić, kliknij prawym przyciskiem myszy swój projekt-> właściwości-> kompilator Java i wybierz taki, który jest wyższy niż 1,5.
Rose
1
Czy ktoś może pomyśleć o przykładzie, który faktycznie uzasadnia odpowiedź (implementacja interfejsów zamiast zastępowania podstawowych metod)? Dużym plusem jest dla mnie to, że pomaga ustalić oczekiwania czytelników dotyczące tego, w jaki sposób i za pomocą jakiej konkretnej metody można zastosować.
Joe Lee-Moyet
103

Uważam, że zachowanie javaca zmieniło się - w wersji 1.5 zabraniał adnotacji, w wersji 1.6 tak nie jest. Adnotacja zapewnia dodatkową kontrolę czasu kompilacji, więc jeśli używasz wersji 1.6, wybrałbym to.

Jon Skeet
źródło
1
Co to jest dodatkowa kontrola?
Michael Carman
17
@ Michael Możesz zauważyć, że któryś interfejs został usunięty.
Sanghyun Lee
68

Zawsze powinieneś adnotować metody, @Overridejeśli są dostępne.

W JDK 5 oznacza to nadpisywanie metod nadklas, w JDK 6, a 7 oznacza nadpisywanie metod nadklas i wdrażanie metod interfejsów. Powodem, jak wspomniano wcześniej, jest to, że pozwala on kompilatorowi wychwytywać błędy, gdy uważasz, że przesłonisz (lub implementujesz) metodę, ale w rzeczywistości definiujesz nową metodę (inną sygnaturę).

equals(Object)Porównaniu z equals(YourObject)przykładem jest standardowym przykładem, ale to samo można powołać się na implementacji interfejsu.

Wyobrażam sobie, że adnotacja metod implementacji interfejsów nie jest obowiązkowa, ponieważ JDK 5 oznaczył to jako błąd kompilacji. Jeśli JDK 6 uczyni tę adnotację obowiązkową, złamałoby to kompatybilność wsteczną.

Nie jestem użytkownikiem Eclipse, ale w innych IDE (IntelliJ) @Overrideadnotacja jest dodawana tylko podczas implementacji metod interfejsu, jeśli projekt jest ustawiony jako projekt JDK 6+. Wyobrażam sobie, że Eclipse jest podobny.

Wolałbym jednak zobaczyć inną adnotację dla tego zastosowania, być może @Implementsadnotację.

GKelly
źródło
11

JDK 5.0 nie pozwala na stosowanie @Overrideadnotacji, jeśli implementujesz metodę zadeklarowaną w interfejsie (błąd kompilacji), ale JDK 6.0 na to pozwala. Być może możesz skonfigurować preferencje projektu zgodnie ze swoimi wymaganiami.

Cichy wojownik
źródło
4

Jeśli konkretna klasa nie zastępuje metody abstrakcyjnej, użycie @Overridedo implementacji jest sprawą otwartą, ponieważ kompilator niezmiennie ostrzega przed wszelkimi niewdrożonymi metodami. W takich przypadkach można argumentować, że szkodzi to czytelności - to więcej rzeczy do przeczytania w kodzie i, w mniejszym stopniu, jest on wywoływany, @Overridea nie @Implement.

juanchito
źródło
3

Przesłonięcie własnych metod odziedziczonych po twoich klasach zwykle nie spowoduje przerwania refaktoryzacji przy użyciu ide. Ale jeśli zastąpisz metodę odziedziczoną z biblioteki, zaleca się jej użycie. Jeśli tego nie zrobisz, często nie pojawi się błąd przy późniejszej zmianie biblioteki, ale dobrze ukryty błąd.

Arne Burmeister
źródło
3

To nie jest problem z JDK. W Eclipse Helios umożliwia adnotację @Override dla zaimplementowanych metod interfejsu, w zależności od JDK 5 lub 6. Podobnie jak w przypadku Eclipse Galileo, adnotacja @Override jest niedozwolona, ​​w zależności od JDK 5 lub 6.

lwpro2
źródło
2

Dla mnie często jest to jedyny powód, dla którego kod wymaga Java 6 do kompilacji. Nie jestem pewien, czy warto.

Fabian Steeg
źródło
2

Czytając javadoc w java8, możesz znaleźć następujące informacje w deklaracji zastąpienia interfejsu:

Jeśli metoda jest opatrzona adnotacją za pomocą tego typu kompilatorów, wymagane jest wygenerowanie komunikatu o błędzie, chyba że spełniony jest przynajmniej jeden z następujących warunków:

  • Metoda zastępuje lub implementuje metodę zadeklarowaną w nadtypie.
  • Metoda ma podpis, który jest równoważny z podpisem dowolnej metody publicznej zadeklarowanej w {@linkplain Object}.

Tak więc, przynajmniej w java8, powinieneś użyć @Override na implementacji metody interfejsu.

Zhao Pengfei
źródło
1

Sam Eclipse doda @Overrideadnotację, gdy powiesz jej, aby „generowała metody niezaimplementowane” podczas tworzenia klasy implementującej interfejs.

savetheclocktower
źródło
1

Problem z włączeniem @Overridepolega na tym, że sprawia, że ​​myślisz, że zapomniałeś wywołać super.theOverridenMethod()metodę, co jest bardzo mylące . To powinno być krystalicznie czyste. Być może Java powinna oferować @Interfacedo użycia tutaj. No cóż, kolejna na wpół osamotniona osobliwość Java ...

spujia
źródło
3
Wywołanie super, gdy nie implementuje interfejsu, nie jest czymś, co zawsze trzeba lub chcesz zrobić. Czasami dodajesz funkcjonalność - tak ją nazywasz. Innym razem zamieniasz funkcjonalność, więc jej nie nazywaj. Autor interfejsu API powinien udokumentować, czy opiera się na wewnętrznej funkcjonalności, czy nie, i utworzyć udokumentowaną umowę dotyczącą tego, w jaki sposób klasa może zostać odpowiednio rozszerzona.
lilbyrdie
1

W java 6 i nowszych wersjach można użyć @Overridemetody implementującej interfejs.

Ale nie sądzę, żeby miało to sens: przesłonięcie oznacza, że ​​masz metodę w superklasie i implementujesz ją w podklasie.

Jeśli wdrażasz interfejs, myślę, że powinniśmy użyć @Implementlub coś innego, ale nie @Override.

ZhaoGang
źródło
0

W przypadku interfejsu użycie @Override spowodowało błąd kompilacji. Musiałem to usunąć.

Komunikat o błędzie poszedł „ The method getAllProducts() of type InMemoryProductRepository must override a superclass method”.

Przeczytał także „ One quick fix available: Remove @Override annotation.

To było na Eclipse 4.6.3, JDK 1.8.0_144.

Park JongBum
źródło
0

Jeśli klasa implementująca interfacejest abstractklasą, @Overridewarto upewnić się, że implementacja dotyczy interfacemetody; bez klasa będzie tylko skompilować grzywny, nawet jeśli podpis metoda realizacja nie pasuje metody zadeklarowane w ; niedopasowana metoda pozostanie niewdrożona. Dokument Java cytowany przez @Zhao@Overrideabstractinterfaceinterface

Metoda zastępuje lub implementuje metodę zadeklarowaną w nadtypie

wyraźnie odnosi się do abstractsuperklasy; interfacenie można nazwać supertypem. Jest więc @Overridezbędny i nie ma sensu w przypadku interfaceimplementacji metod w konkretnych klasach.

Madhu
źródło