Sollten wir die Methodenimplementierung einer Schnittstelle überschreiben?

431

Sollte eine Methode, die eine Schnittstellenmethode implementiert, mit Anmerkungen versehen werden @Override ?

Der Javadoc der OverrideAnmerkung sagt:

Gibt an, dass eine Methodendeklaration eine Methodendeklaration in einer Oberklasse überschreiben soll. Wenn eine Methode mit diesem Annotationstyp mit Anmerkungen versehen ist, eine Oberklassenmethode jedoch nicht überschreibt, müssen Compiler eine Fehlermeldung generieren.

Ich denke nicht, dass eine Schnittstelle technisch eine Superklasse ist. Oder ist es?

Question Elaboration

Benno Richters
quelle
5
Wow, diese Frage könnte kürzer sein, aber es ist die Frage, die ich brauchte. Vielen Dank
Dan Rosenstark
1
Ich kann den Ersatz für den @ Override-Artikel nicht finden (Oracle hat kürzlich die alten Sun-Blogs verschoben). Wissen Sie, wie Sie es finden können?
Bill the Lizard
4
Wir sollten jetzt (2015) eine Anmerkung zu @Implement (s) haben. Das wird die Dinge klar machen!
Alex
3
sollten wir jetzt (2015) @Override mit Java 8 verwenden?
Lorenzo Sciuto

Antworten:

304

Sie sollten nach Möglichkeit @Override verwenden. Es verhindert, dass einfache Fehler gemacht werden. Beispiel:

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

Dies wird nicht kompiliert, da es nicht richtig überschrieben wird public boolean equals(Object obj).

Gleiches gilt für Methoden, die eine Schnittstelle implementieren (nur 1.6 und höher ) oder die Methode einer Superklasse überschreiben.

jjnguy
quelle
150
Beachten Sie, dass Sie die Annotation @Override nicht zu einer Methode hinzufügen können , die eine Schnittstelle in Java 5 implementiert - sie generiert einen Fehler. Es ist in Java 6 erlaubt.
Bill Michell
17
Ähm, nein, das tut es nicht. Tatsächlich fügt Eclipse @Override automatisch ein, wenn Methoden ausgefüllt werden, die eine Schnittstelle implementieren.
jjnguy
14
-1, bis die Antwort eine Erwähnung des unterschiedlichen Verhaltens von Java 1.5 bis 1.6 hinsichtlich der Implementierung einer Schnittstellenmethode enthält. Nur weil ich gesehen habe, dass es ein verwirrender Aspekt für die Menschen ist und es wirklich eine Erwähnung verdient.
Grundlefleck
2
Wenn sich Eclipse beschwert, aktualisieren Sie ur jdk auf> 1,5 und ändern Sie die Compiler-Konformitätsstufe auf 1,6 oder 1,7. Klicken Sie dazu mit der rechten Maustaste auf Ihr Projekt-> Eigenschaften-> Java-Compiler und wählen Sie einen aus, der höher als 1,5 ist.
Rose
1
Kann sich jemand ein Beispiel vorstellen, das die Antwort tatsächlich rechtfertigt (Schnittstellen implementieren, anstatt Basismethoden zu überschreiben)? Ein großes Plus für mich ist, dass es den Lesern hilft, die Erwartungen zu erfüllen, wie und mit welcher Methode eine bestimmte Methode angewendet werden kann.
Joe Lee-Moyet
103

Ich glaube, dass sich das Javac-Verhalten geändert hat - mit 1.5 wurde die Annotation verboten, mit 1.6 nicht. Die Anmerkung bietet eine zusätzliche Überprüfung zur Kompilierungszeit. Wenn Sie also 1.6 verwenden, würde ich mich dafür entscheiden.

Jon Skeet
quelle
1
Was ist der zusätzliche Scheck?
Michael Carman
17
@Michael Sie können feststellen, ob eine Schnittstelle gelöscht wurde.
Sanghyun Lee
68

Sie sollten Methoden immer mit Anmerkungen versehen, @Overridewenn sie verfügbar sind.

In JDK 5 bedeutet dies, Methoden von Oberklassen zu überschreiben, in JDK 6 und 7 bedeutet dies, Methoden von Oberklassen zu überschreiben und Methoden von Schnittstellen zu implementieren. Der Grund dafür ist, wie bereits erwähnt, dass der Compiler Fehler abfangen kann, wenn Sie glauben, eine Methode zu überschreiben (oder zu implementieren), aber tatsächlich eine neue Methode definieren (andere Signatur).

Das Beispiel equals(Object)vs. equals(YourObject)ist ein Standardbeispiel, aber das gleiche Argument kann für Schnittstellenimplementierungen angeführt werden.

Ich würde mir vorstellen, dass es nicht zwingend erforderlich ist, Implementierungsmethoden für Schnittstellen mit Anmerkungen zu versehen, weil JDK 5 dies als Kompilierungsfehler gekennzeichnet hat. Wenn JDK 6 diese Anmerkung obligatorisch machen würde, würde dies die Abwärtskompatibilität beeinträchtigen.

Ich bin kein Eclipse-Benutzer, aber in anderen IDEs (IntelliJ) wird die @OverrideAnmerkung nur beim Implementieren von Schnittstellenmethoden hinzugefügt, wenn das Projekt als JDK 6+ -Projekt festgelegt ist. Ich würde mir vorstellen, dass Eclipse ähnlich ist.

Ich hätte es jedoch vorgezogen, eine andere Anmerkung für diese Verwendung zu sehen, möglicherweise eine @ImplementsAnmerkung.

GKelly
quelle
11

In JDK 5.0 können Sie keine @OverrideAnmerkungen verwenden, wenn Sie eine in der Schnittstelle deklarierte Methode implementieren (deren Kompilierungsfehler), in JDK 6.0 ist dies jedoch zulässig. Möglicherweise können Sie Ihre Projekteinstellungen entsprechend Ihren Anforderungen konfigurieren.

Stiller Krieger
quelle
4

Wenn eine konkrete Klasse eine abstrakte Methode nicht überschreibt , ist die Verwendung @Overridefür die Implementierung eine offene Angelegenheit, da der Compiler Sie ausnahmslos vor nicht implementierten Methoden warnt. In diesen Fällen kann argumentiert werden, dass dies die Lesbarkeit beeinträchtigt - es sind mehr Dinge, die in Ihrem Code gelesen werden müssen, und in geringerem Maße wird es aufgerufen @Overrideund nicht @Implement.

Juanchito
quelle
3

Das Überschreiben Ihrer eigenen Methoden, die von Ihren eigenen Klassen geerbt wurden, wird bei Refactorings mit einer Idee normalerweise nicht unterbrochen. Wenn Sie jedoch eine von einer Bibliothek geerbte Methode überschreiben, wird empfohlen, sie zu verwenden. Wenn Sie dies nicht tun, erhalten Sie bei einer späteren Bibliotheksänderung häufig keinen Fehler, sondern einen gut versteckten Fehler.

Arne Burmeister
quelle
3

Mit JDK ist das kein Problem. In Eclipse Helios ist die Annotation @Override für implementierte Schnittstellenmethoden zulässig, je nachdem, welches JDK 5 oder 6 vorliegt. Wie bei Eclipse Galileo ist die Annotation @Override nicht zulässig, je nachdem, welches JDK 5 oder 6 vorliegt.

lwpro2
quelle
2

Für mich ist dies oft der einzige Grund, warum für die Kompilierung von Code Java 6 erforderlich ist. Ich bin mir nicht sicher, ob es sich lohnt.

Fabian Steeg
quelle
2

Wenn Sie das Javadoc in Java8 lesen, finden Sie Folgendes in der Deklaration der Schnittstelle Override:

Wenn eine Methode mit diesem Annotationstyp kommentiert wird, müssen Compiler eine Fehlermeldung generieren, es sei denn, mindestens eine der folgenden Bedingungen gilt:

  • Die Methode überschreibt oder implementiert eine in einem Supertyp deklarierte Methode.
  • Die Methode hat eine Signatur, die der einer in {@linkplain Object} deklarierten öffentlichen Methode überschreibt.

Zumindest in Java8 sollten Sie @Override für die Implementierung einer Schnittstellenmethode verwenden.

Zhao Pengfei
quelle
1

Eclipse selbst fügt die @OverrideAnnotation hinzu, wenn Sie anweisen, beim Erstellen einer Klasse, die eine Schnittstelle implementiert, "nicht implementierte Methoden zu generieren".

savetheclocktower
quelle
1

Das Problem beim Einfügen von @Overrideist, dass Sie denken, Sie hätten vergessen, die super.theOverridenMethod()Methode aufzurufen , was sehr verwirrend ist . Dies sollte kristallklar sein. Vielleicht sollte Java ein anbieten @Interface, um hier verwendet zu werden. Na ja, noch eine halbherzige Java-Besonderheit ...

Spujia
quelle
3
Ein Super aufzurufen, wenn Sie keine Schnittstelle implementieren, ist nicht etwas, was Sie immer tun müssen oder wollen. Manchmal fügen Sie Funktionen hinzu - also nennen Sie es. In anderen Fällen ersetzen Sie die Funktionalität, sodass Sie sie nicht aufrufen. Ein API-Autor sollte dokumentieren, ob er auf internen Funktionen basiert oder nicht, und einen dokumentierten Vertrag darüber erstellen, wie die Klasse ordnungsgemäß erweitert werden kann.
Lilbyrdie
1

In Java 6 und späteren Versionen können Sie @Overrideeine Methode zum Implementieren einer Schnittstelle verwenden.

Aber ich halte es nicht für sinnvoll: Überschreiben bedeutet, dass Sie eine Methode in der Superklasse haben und diese in der Unterklasse implementieren.

Wenn Sie eine Schnittstelle implementieren, sollten wir @Implementoder etwas anderes verwenden, aber nicht die @Override.

ZhaoGang
quelle
0

Für die Schnittstelle verursachte die Verwendung von @Override einen Kompilierungsfehler. Also musste ich es entfernen.

Fehlermeldung ging " The method getAllProducts() of type InMemoryProductRepository must override a superclass method".

Es lautete auch " One quick fix available: Remove @Override annotation."

Es war auf Eclipse 4.6.3, JDK 1.8.0_144.

Park JongBum
quelle
0

Wenn die Klasse, die das implementiert, interfaceeine abstractKlasse ist, @Overrideist dies hilfreich, um sicherzustellen, dass die Implementierung für eine interfaceMethode ist. Ohne die würde @Overrideeine abstractKlasse nur dann gut kompiliert, wenn die Signatur der Implementierungsmethode nicht mit der in der interface; Die nicht übereinstimmende interfaceMethode würde als nicht implementiert bleiben. Das von @Zhao zitierte Java-Dokument

Die Methode überschreibt oder implementiert eine in einem Supertyp deklarierte Methode

bezieht sich eindeutig auf eine abstractSuperklasse; Ein interfacekann nicht als Supertyp bezeichnet werden. Ist @Overridealso redundant und für interfaceMethodenimplementierungen in konkreten Klassen nicht sinnvoll .

Madhu
quelle