it-swarm.com.de

Sollen Methoden in einer Java-Schnittstelle mit oder ohne öffentlichen Zugriffsmodifizierer deklariert werden?

Sollen Methoden in einer Java-Schnittstelle mit oder ohne Zugriffsmodifizierer public deklariert werden?

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

Java selbst ist darin nicht konsistent. Siehe zum Beispiel Collection vs. Comparable oder Future vs. ScriptEngine.

265
Benno Richters

Die JLS macht dies klar:

Es ist zulässig, jedoch aus Gründen des Stils entmutigt, den Modifizierer public und/oder abstract für eine in einer Schnittstelle deklarierte Methode redundant anzugeben.

316
Jon Skeet

Der öffentliche Modifizierer sollte in meinen Java-Schnittstellen (meiner Meinung nach) weggelassen werden.

Da es keine zusätzlichen Informationen hinzufügt, lenkt es nur die Aufmerksamkeit von den wichtigen Dingen ab.

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

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
39
Rasmus Faber

Trotz der Tatsache, dass diese Frage schon vor langer Zeit gestellt wurde, würde meiner Meinung nach eine umfassende Beschreibung klarstellen, warum es nicht nötig ist, öffentliche Konzepten vor Methoden und statische Statements vor Konstanten einer Schnittstelle zu verwenden.

Zuallererst werden Interfaces verwendet, um allgemeine Methoden für einen Satz nicht zusammenhängender Klassen anzugeben, für die jede Klasse eine eindeutige Implementierung hat. Daher kann der Zugriffsmodifizierer nicht als privat angegeben werden, da andere Klassen, auf die er überschrieben werden soll, nicht darauf 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 geschützte Zugriffsmodifizierer ebenfalls nicht gültig. Für den Zugriffsmodifizierer haben wir also nur die öffentliche Wahl.

Drittens hat eine Schnittstelle keine Datenimplementierung, einschließlich der Instanzvariablen und -methoden. Wenn es logische Gründe gibt, implementierte Methoden oder Instanzvariablen in eine Schnittstelle einzufügen, muss es sich um eine Superklasse in einer Vererbungshierarchie und nicht um eine Schnittstelle handeln. Da keine Methode in eine Schnittstelle implementiert werden kann, müssen alle Methoden in der Schnittstelle abstrakt sein. 

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

Daher ist die Verwendung von public abstract vor Methoden und public static final vor Konstanten einer Schnittstelle gültig. Da es jedoch keine anderen Optionen gibt, wird sie als redundant betrachtet und nicht verwendet. 

8
Leo The Four

Ich würde vermeiden, Modifizierer zu setzen, die standardmäßig angewendet werden. Wie bereits erwähnt, kann dies zu Inkonsistenz und Verwirrung führen.

Das Schlimmste, das ich gesehen habe, ist eine Schnittstelle mit Methoden, die als abstract...

5
PhiLho

Ich habe deklarierte Methoden mit dem Modifizierer public verwendet, da der Code dadurch lesbarer wird, insbesondere mit der Syntaxhervorhebung. In unserem neuesten Projekt haben wir jedoch Checkstyle verwendet, das eine Warnung mit der Standardkonfiguration für public-Modifikatoren für Schnittstellenmethoden anzeigt. Daher habe ich auf diese Einstellungen verzichtet.

Ich bin mir nicht wirklich sicher, was am besten ist, aber eine Sache, die ich wirklich nicht mag, ist public abstract für Schnittstellenmethoden. Eclipse macht dies manchmal beim Refactoring mit "Extract Interface".

5
cretzel

Ich schreibe immer, was ich verwenden würde, wenn es keine Schnittstelle gab und ich eine direkte Implementierung schrieb, d. H. Ich würde public verwenden.

4
JeeBee

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

Eine Methode in einer Schnittstelle ist standardmäßig abstrakt, um die implementierende Klasse zu zwingen, eine Implementierung bereitzustellen, und sie ist standardmäßig öffentlich, sodass die implementierende Klasse dazu Zugriff hat.

Das Hinzufügen dieser Modifizierer in Ihrem Code ist redundant und unbrauchbar und kann nur zu dem Schluss führen, dass Ihnen Kenntnisse und/oder Kenntnisse über Java-Grundlagen fehlen.

3
Iuliana Cosmina

Ich bevorzuge es überspringen, ich habe irgendwo gelesen, dass Schnittstellen standardmäßig public und abstract sind. 

Zu meiner Überraschung verwendet das Buch - Head First Design Patterns , public mit Interface-Deklaration und Interface-Methoden ... das brachte mich dazu, noch einmal zu überdenken und landete in diesem Beitrag. 

Ich denke sowieso, dass redundante Informationen ignoriert werden sollten. 

3
Pradeep Sharma

Mit der Einführung der Modifizierer private, static, default für Schnittstellenmethoden in Java 8/9 werden die Dinge komplizierter und ich neige zu der Ansicht, dass vollständige Deklarationen besser lesbar sind (benötigt Java 9 zum 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() {}

}
3
Werner Thumann

Es ist absolut subjektiv. Ich lasse den redundanten Modifizierer public weg, da er wie Unordnung wirkt. Wie bereits erwähnt, ist Konsistenz der Schlüssel zu dieser Entscheidung.

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

1
serg10

Ich stimme nicht mit der populären Antwort überein, dass die Öffentlichkeit impliziert, dass es andere Optionen gibt, und dass sie nicht da sein sollte. Tatsache ist, dass es ab Java 9 andere Optionen gibt.

Ich denke stattdessen sollte Java die Angabe von "public" erzwingen/verlangen. Warum? Das Fehlen eines Modifizierers bedeutet "Paketzugriff" an anderen Stellen, und dies als Sonderfall zu haben, führt zu Verwirrung. Wenn Sie einfach einen Kompilierungsfehler mit einer eindeutigen Meldung gemacht haben (z. B. "Paketzugriff ist in einer Schnittstelle nicht zulässig."), Würden wir die offensichtliche Mehrdeutigkeit beseitigen, die durch die Option "Öffentlich" ausgeschlossen wird.

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 eines Interfaces kann als public oder Private (§6.6) deklariert werden. Wenn kein Zugriffsmodifizierer angegeben wird, ist die Methode implizit public. Sie ist zulässig, wird jedoch entmutigt als style, um den public Modifier für eine Methodendeklaration in einer Schnittstelle redundant anzugeben. "

Sehen Sie, dass 'privat' IS jetzt erlaubt ist. Ich denke, der letzte Satz hätte aus der JLS entfernt werden sollen. Es ist bedauerlich, dass das "implizit öffentliche" Verhalten jemals erlaubt wurde, da es jetzt wahrscheinlich aus Gründen der Abwärtskompatibilität bleiben wird und zu der Verwirrung führt, dass das Fehlen des Zugriffsmodifizierers "public" in Schnittstellen und "package" andernorts bedeutet.

0
swpalmer