Sollten Methoden in einer Java-Schnittstelle mit oder ohne Public Access Modifier deklariert werden?

292

Sollten Methoden in einer Java-Schnittstelle mit oder ohne publicZugriffsmodifikator deklariert werden ?

Technisch spielt es natürlich keine Rolle. Eine Klassenmethode, die ein implementiert, interfaceist immer public. Aber was ist eine bessere Konvention?

Java selbst ist darin nicht konsistent. Siehe zum Beispiel Collectiongegenüber Comparableoder Futuregegenüber ScriptEngine.

Benno Richters
quelle
22
Es ist schlecht , weil es als öffentliches Schreiben bedeutet , dass es kann nicht-öffentlich sein
Pacerier
8
Sie sollten redundante Syntax jeglicher Form vermeiden.
Marquis von Lorne
3
@Pacerier, während ich damit einverstanden , dass es schlecht ist die Verwendung publicin diesem Zusammenhang Methoden Standard - Schnittstelle können jetzt (mit Java - 9) werden privat. Ich schlage vor, Sie entfernen Ihren Kommentar, da er veraltet ist.
Aioobe
2
Ja, die Dinge sind Änderungen vorbehalten in Java 9. „als öffentliche Schreiben bedeutet , dass es kann nicht-öffentlich sein“ . Da genau , dass 9 in Java möglich zu sein scheint, ist dieses Argument nun zugunsten der Tat auszuschreiben public.
MC Emperor

Antworten:

334

Das JLS macht dies klar:

Es ist zulässig, aber aus Stilgründen wird davon abgeraten, den publicund / oder abstractModifikator für eine in einer Schnittstelle deklarierte Methode redundant anzugeben .

Jon Skeet
quelle
6
Der obige JLS-Link war zu dem Zeitpunkt, als ich ihn las, für Java 7. Nach den Kommentaren zu Java 9, das nicht öffentliche Methoden zulässt, wollte ich nur bestätigen, dass für SE9 JLS immer noch ein sehr ähnlicher Wortlaut vorhanden ist . ( publicTeil ist gleich, and/or abstractTeil wurde fallen gelassen)
OzgurH
3
Immer noch wahr in SE11 JLS
Ortomala Lokni
44

Der öffentliche Modifikator sollte in Java-Interfaces weggelassen werden (meiner Meinung nach).

Da keine zusätzlichen Informationen hinzugefügt werden, wird die Aufmerksamkeit nur von den wichtigen Dingen abgelenkt.

Die meisten Style-Guides empfehlen, dass Sie es weglassen, aber das Wichtigste ist natürlich, dass Sie in Ihrer Codebasis und insbesondere für jede Benutzeroberfläche konsistent sind. Das folgende Beispiel könnte leicht jemanden verwirren, der Java nicht zu 100% fließend spricht:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
Rasmus Faber
quelle
3
Haben Sie einen Link zu einem solchen Styleguide?
Benno Richters
9
Konsistenz ist bei weitem das Wichtigste und die Antwort auf 99% dieser Art von Fragen.
SCdF
Einverstanden bezüglich: Konsistenz. Etwas für Ihre Codierungsstandards dokumentiert Jungs :)
JeeBee
2
Bno: Ein Beispiel ist die Java-Sprachspezifikation, ein anderes ist Checkstyle.
Rasmus Faber
9

Trotz der Tatsache, dass diese Frage vor langer Zeit gestellt wurde, würde eine umfassende Beschreibung meiner Meinung nach klarstellen, warum es nicht erforderlich ist, public abstract vor Methoden und public static final vor Konstanten einer Schnittstelle zu verwenden.

Zunächst werden Schnittstellen verwendet, um allgemeine Methoden für eine Reihe nicht verwandter Klassen anzugeben, für die jede Klasse eine eindeutige Implementierung hat. Daher ist es nicht möglich, den Zugriffsmodifikator als privat anzugeben, da andere Klassen, auf die überschrieben werden soll, nicht auf ihn zugreifen können.

Zweitens kann man zwar Objekte eines Schnittstellentyps initiieren, aber eine Schnittstelle wird von den Klassen realisiert, die sie implementieren und nicht vererbt. Und da eine Schnittstelle möglicherweise von verschiedenen nicht verwandten Klassen implementiert (realisiert) wird, die sich nicht im selben Paket befinden, ist der Modifikator für geschützten Zugriff ebenfalls nicht gültig. Für den Zugriffsmodifikator bleibt uns also nur die öffentliche Wahl.

Drittens hat eine Schnittstelle keine Datenimplementierung, einschließlich der Instanzvariablen und -methoden. Wenn es einen logischen Grund gibt, implementierte Methoden oder Instanzvariablen in eine Schnittstelle einzufügen, muss es sich um eine Oberklasse in einer Vererbungshierarchie und nicht um eine Schnittstelle handeln. In Anbetracht dieser Tatsache müssen alle Methoden in der Schnittstelle abstrakt sein, da keine Methode in einer Schnittstelle implementiert werden kann.

Viertens kann Interface nur Konstanten als Datenelemente enthalten, was bedeutet, dass sie endgültig sein müssen und natürlich Endkonstanten als statisch deklariert werden, um nur eine Instanz von ihnen zu behalten. Daher ist das statische Finale auch ein Muss für Schnittstellenkonstanten.

Zusammenfassend lässt sich sagen, dass die Verwendung von public abstract vor Methoden und public static final vor Konstanten einer Schnittstelle gültig ist, aber da es keine anderen Optionen gibt, wird sie als redundant betrachtet und nicht verwendet.

Leo die vier
quelle
7

Mit der Einführung von private, static, defaultModifikatoren für Interface - Methoden in Java 8/9, werden die Dinge komplizierter und ich neige dazu zu denken , dass die vollständigen Erklärungen besser lesbar sind (benötigt Java 9 zu kompilieren):

public interface MyInterface {

    //minimal
    int CONST00 = 0;
    void method00();
    static void method01() {}
    default void method02() {}
    private static void method03() {}
    private void method04() {}

    //full
    public static final int CONST10 = 0;
    public abstract void method10();
    public static void method11() {}
    public default void method12() {}
    private static void method13() {}
    private void method14() {}

}
Werner Thumann
quelle
5

Ich würde es vermeiden, Modifikatoren einzufügen, die standardmäßig angewendet werden. Wie bereits erwähnt, kann dies zu Inkonsistenzen und Verwirrung führen.

Das Schlimmste, was ich gesehen habe, ist eine Schnittstelle mit deklarierten Methoden abstract...

PhiLho
quelle
5

Ich habe Deklarationsmethoden mit dem publicModifikator verwendet, weil dadurch der Code besser lesbar wird, insbesondere bei der Hervorhebung der Syntax. In unserem neuesten Projekt haben wir jedoch Checkstyle verwendet, das eine Warnung mit der Standardkonfiguration für publicModifikatoren für Schnittstellenmethoden anzeigt. Daher habe ich darauf umgestellt, diese zu deaktivieren.

Ich bin mir also nicht sicher, was am besten ist, aber eine Sache, die ich wirklich nicht mag, ist die Verwendung public abstractvon Schnittstellenmethoden. Eclipse tut dies manchmal beim Refactoring mit "Schnittstelle extrahieren".

Cretzel
quelle
2
Aber nur wenn Sie die beiden Kontrollkästchen aktivieren, deklarieren Sie Methoden als öffentlich, abstrakt.
MetroidFan2002
4

Ich schreibe immer, was ich verwenden würde, wenn es keine Schnittstelle gäbe, und ich schreibe eine direkte Implementierung, dh ich würde verwenden public.

JeeBee
quelle
6
Würden Sie auch alle Schnittstellenmethoden explizit als abstrakt deklarieren?
Dan Dyer
4
Es ist eine Schnittstelle, keine abstrakte Klasse. In Bezug auf "öffentlich" sind es 7 Zeichen, die Sie eingegeben haben, als Sie darüber nachdenken, große Sache! Und so wird es auch in der Implementierung definiert, dh +1 für die Konsistenz, wobei -1 für Redundanz ausgeglichen wird.
JeeBee
3

Ich überspringe es lieber, ich lese irgendwo, dass Schnittstellen standardmäßig sind, publicund abstract.

Zu meiner Überraschung verwendet das Buch - Head First Design Patterns - publicSchnittstellendeklarationen und Schnittstellenmethoden ... das hat mich noch einmal zum Umdenken gebracht und ich bin auf diesem Beitrag gelandet.

Ich denke, redundante Informationen sollten ignoriert werden.

Pradeep Sharma
quelle
1
Wenn Sie den publicZugriffsmodifikator in der Schnittstellendeklaration weglassen, ist er standardmäßig nicht öffentlich und abstrakt. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad
3

Ich bin mit der populären Antwort nicht einverstanden, dass Öffentlichkeit impliziert, dass es andere Optionen gibt und es daher nicht geben sollte. Tatsache ist, dass es jetzt mit Java 9 und darüber hinaus andere Optionen gibt.

Ich denke stattdessen sollte Java die Angabe von 'public' erzwingen / verlangen. Warum? Weil das Fehlen eines Modifikators überall sonst "Paket" -Zugriff bedeutet und dies als Sonderfall gilt, führt dies zu Verwirrung. Wenn Sie es einfach zu einem Kompilierungsfehler mit einer eindeutigen Meldung machen würden (z. B. "Paketzugriff ist in einer Schnittstelle nicht zulässig."), Werden wir die offensichtliche Unklarheit beseitigen, die sich aus der Option ergibt, "öffentlich" wegzulassen.

Beachten Sie den aktuellen Wortlaut unter: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

"Eine Methode im Hauptteil einer Schnittstelle kann als öffentlich oder privat deklariert werden (§6.6). Wenn kein Zugriffsmodifikator angegeben wird, ist die Methode implizit öffentlich. Es ist zulässig, aber aus Stilgründen wird davon abgeraten, die Öffentlichkeit redundant anzugeben Modifikator für eine Methodendeklaration in einer Schnittstelle. "

Sehen Sie, dass "privat" jetzt erlaubt ist. Ich denke, der letzte Satz hätte aus dem JLS entfernt werden sollen. Es ist bedauerlich, dass das "implizit öffentliche" Verhalten jemals zugelassen wurde, da es nun wahrscheinlich aus Gründen der Abwärtskompatibilität bestehen bleibt und zu der Verwirrung führt, dass das Fehlen des Zugriffsmodifikators "öffentlich" in Schnittstellen und "Paket" an anderer Stelle bedeutet.

swpalmer
quelle
2

Der Grund dafür, dass Methoden in Schnittstellen standardmäßig öffentlich und abstrakt sind, erscheint mir ziemlich logisch und offensichtlich.

Eine Methode in einer Schnittstelle, die standardmäßig abstrakt ist, um die implementierende Klasse zur Bereitstellung einer Implementierung zu zwingen, ist standardmäßig öffentlich, sodass die implementierende Klasse Zugriff darauf hat.

Das Hinzufügen dieser Modifikatoren zu Ihrem Code ist redundant und nutzlos und kann nur zu dem Schluss führen, dass Ihnen Kenntnisse und / oder Verständnis der Java-Grundlagen fehlen.

Iuliana Cosmina
quelle
Sie können aber auch abstrakte Methoden mit geschütztem Zugriff implementieren - in einer abstrakten Klasse. Öffentlichkeit ist also keine Voraussetzung. Das Hinzufügen von expliziten Elementen, die mit den Standardeinstellungen identisch sind, ist immer redundant, aber nicht immer nutzlos.
Swpalmer
Die Frage betrifft jedoch Schnittstellen. Ich wollte nicht abschweifen. Ich meine, seit Java 8 können wir auch über private und Standardmethoden in Schnittstellen sprechen, oder? Diese Diskussion kann also ziemlich lang sein, wenn wir wollen. ;)
Iuliana Cosmina
1

Es ist total subjektiv. Ich lasse den redundanten publicModifikator weg, da es wie Unordnung erscheint. Wie von anderen erwähnt, ist Konsistenz der Schlüssel zu dieser Entscheidung.

Es ist interessant festzustellen, dass die C # -Sprachendesigner beschlossen haben, dies durchzusetzen. Das Deklarieren einer Schnittstellenmethode als öffentlich in C # ist tatsächlich ein Kompilierungsfehler. Konsistenz ist wahrscheinlich nicht sprachübergreifend wichtig, daher denke ich, dass dies für Java nicht wirklich direkt relevant ist.

serg10
quelle
-9

Die Benutzer lernen Ihre Benutzeroberfläche anhand der Code-Vervollständigung in ihrer IDE oder in Javadoc und nicht anhand des Lesens der Quelle. Es macht also keinen Sinn, "öffentlich" in die Quelle zu setzen - niemand liest die Quelle.

Tim Boudreau
quelle
8
Ich muss der Aussage wirklich widersprechen, dass niemand die Quelle liest. Ich denke, viele Leute verwenden zum Beispiel F3 in Eclipse, um in den Code zu zoomen. Tools wie Maven bieten aus einem bestimmten Grund die Möglichkeit, die Quellen und nicht nur JavaDoc herunterzuladen.
Benno Richters
Dies ist nicht der genaue Grund, warum publiceiner Schnittstelle kein Zugriffsmodifikator hinzugefügt wird. Es ist beabsichtigt und nach sorgfältiger Überlegung dahinter.
MTK