web-dev-qa-db-de.com

In Schnittstellen geschützt

Warum sind alle Methoden in einer interface-Definition implizit public? Warum lässt es keine protected-Methode zu?

93
Swaranga Sarma

Denn eine Schnittstelle soll "was Sie außerhalb der Klasse sehen können" bedeuten. Es wäre nicht sinnvoll, nichtöffentliche Methoden hinzuzufügen.

59
Raveline

Obwohl der häufig zitierte Grund darin liegt, dass "Schnittstellen öffentliche APIs definieren", denke ich, dass dies eine übermäßige Vereinfachung darstellt. (Und es riecht auch nach Kreislogik.)

  • Eine verschachtelte Schnittstelle kann geschützt oder privat sein, und wenn dies der Fall ist, definiert sie überhaupt keine öffentliche Schnittstelle.

  • Es wäre nicht sinnlos, Schnittstellen zu haben, die eine Mischung von Zugriffsmodifizierern haben. z.B. teilweise öffentlich und teilweise auf andere Klassen im selben Paket wie die Schnittstelle beschränkt. Tatsächlich könnte dies in einigen Fällen nützlich sein, IMO. 

Eigentlich denke ich, dass der Teil der Argumentation , um Mitglieder einer Schnittstelle implizit öffentlich zu machen, ist, dass es Java einfacher macht :

  • Implizit öffentliche Schnittstellenmitglieder sind für Programmierer einfacher zu handhaben. Wie oft haben Sie Code (Klassen) gesehen, bei denen die Methoden-Zugriffsmodifizierer scheinbar zufällig ausgewählt wurden? Viele "normale" Programmierer haben Schwierigkeiten zu verstehen, wie Java-Abstraktionsgrenzen am besten verwaltet werden1. Das Hinzufügen von public/protected/package zu Schnittstellen macht es ihnen noch schwieriger. 

  • Implizit öffentliche Schnittstellenmitglieder vereinfachen die Sprachspezifikation ... und damit die Aufgabe für Java-Compiler-Autoren und die Benutzer, die die Reflection-APIs implementieren.

Diese Denkweise macht die "Schnittstellen definieren öffentliche APIs" zu einer Konsequenz (oder Charakteristik) des Sprachdesigns ... und nicht umgekehrt. In der Realität haben sich die beiden Gedankengänge wahrscheinlich in den Köpfen der Java-Designer parallel entwickelt.


1 - Top-Gun-Programmierer haben natürlich keine Probleme mit diesen Dingen und begrüßen möglicherweise eine reichhaltigere Palette von Zugriffskontrollfunktionen. Aber was passiert, wenn der Code zur Pflege an einen anderen Benutzer übergeben wird?

47
Stephen C

Ich muss sagen, dass diese Frage durch die Einführung von Standardmethoden in Java 8 wieder geöffnet wurde. Das Projekt, an dem ich gerade arbeite, ist, ähnlich wie die grundlegende Natur einer Schnittstelle, dazu gedacht, die Intention von der Implementierung abzugrenzen.

Es gibt mehrere Fälle, in denen ich meinen Code mit einer "default protected" -Methode drastisch vereinfachen könnte. Es stellt sich heraus, dass das eigentlich nicht funktioniert, da Schnittstellen immer noch an Java 7-Logik gebunden sind. Eine normale geschützte Methode macht aus den oben genannten Gründen keinen Sinn. Wenn jedoch für eine öffentliche Standardmethode eine Low-Level-Ressource erforderlich ist, die sich wahrscheinlich nicht ändert und durch eine geschützte Methode bereitgestellt werden kann, scheint es mir, dass "Standard-geschützte" Arbeit nicht nur saubereren Code aufrechterhält, sondern auch zukünftige Benutzer davor schützt versehentlicher Missbrauch.

(Dies ändert auf tragische Weise nichts an der Tatsache, dass ich meinen Code immer noch mit ansonsten unnötigen Abstracts überkomplizieren muss; ich beabsichtige jedoch, eine Funktionsanforderung bei Oracle einzureichen.)

17
Michael Oberlin

Weil Schnittstellen öffentliche APIs definieren. Alles, was geschützt wird, ist ein internes Detail, das nicht in eine Schnittstelle gehört.

Sie können abstrakte Klassen mit geschützten abstrakten Methoden verwenden, die Schnittstellen sind jedoch auf öffentliche Methoden und öffentliche statische Endfelder beschränkt.

9

Vielleicht, weil es sich um eine Schnittstelle handelt, d. H., Es ist dazu da, den Kunden mitzuteilen, was sie mit Instanzen tun können, anstatt ihnen zu sagen, was sie nicht können.

7
Ingo

Ich stark bin der Meinung, dass Interfaces geschützte Methoden zulassen sollten; wer hat gesagt, dass schnittstellen für alle auf der ganzen welt sichtbar sein müssen? Was Ihren Standpunkt angeht, dass es "gewöhnliche" (sprich: inkompetente) Programmierer verwirren könnte: Bei OOP geht es hauptsächlich darum, Objekte, Klassen, Pakete usw. richtig zu strukturieren, wenn es einem Programmierer schwer fällt, alles zu tun Das ist richtig, er hat ein viel größeres Problem. Java war built für diese Art von Dingen.

5
IntelliData

Eine Schnittstelle soll als "Vertrag" für die Außenwelt verwendet werden. Wenn Sie geschützte Methoden verwenden möchten, ist es wahrscheinlich besser, eine abstrakte Klasse zu verwenden (wenn dies natürlich in Java verfügbar ist) . Wiki

Dieser Beitrag hat wahrscheinlich auch einige großartige Antworten: Warum kann ich keine Benutzer der Benutzeroberfläche schützen?

4
Jan_V

Da eine implementierende Klasse ALLE in Ihrer Schnittstelle deklarierten Methoden implementieren muss, was würde passieren, wenn Ihre implementierende Klasse in einem anderen Paket enthalten wäre?

3
dm76

Schnittstelle Wenn Sie etwas wie Sie beschrieben verwenden möchten, fahren Sie mit abstrakten Klassen oder verschachtelten Schnittstellen fort.

Ein Auszug aus dem Code Style über Schnittstellenvariablen, der jedoch immer noch für Methoden gilt:

Schnittstellenvariablen sind implizit öffentlich, da Schnittstellen dazu vorgesehen sind, eine Anwendungsprogrammierschnittstelle (API) bereitzustellen, auf die Java-Programmierer vollständig zugreifen können, um sie in ihren eigenen Anwendungen zu referenzieren und zu implementieren. Da eine Schnittstelle in Java-Paketen verwendet werden kann, die sich von ihren eigenen unterscheiden, stellt die öffentliche Sichtbarkeit sicher, dass Programmcode auf die Variable ..__ zugreifen kann.
2
grizzly

Geschützte Methoden sind immer nur für Unterklassen zugänglich, wenn die Basisklasse durch Unterklasse erweitert wird.

Bei einer Schnittstelle erweitert die Unterklasse die Schnittstelle niemals. Es implementiert die Schnittstelle.

Geschützte Methoden sind über extend und nicht mit implement zugänglich. 

2
Aftaab Siddiki

Das Deklarieren interner Subinterfaces ist eine gute Vorgehensweise, aber Sie können Ihre internen Methoden in einer Java-Schnittstelle technisch nicht als protected deklarieren.

Natürlich können Sie eine weitere Schnittstelle für den internen Gebrauch erstellen, die die öffentliche Schnittstelle erweitert:

public interface YourPublicInterface {

    public void doThing1();

    public void doThing2();

    public void doThing3();

    interface Internal extends YourPublicInterface {

        void doAnyInternalThing1();

        void doAnyInternalThing2();

    }

}

Sie können die Internal-Schnittstelle innerhalb des Pakets verwenden, Sie sollten jedoch jeden Untertyp von YourPublicInterface akzeptieren (in öffentlichen Methoden):

public class AClassInYourPackage {

    public void someMethod(YourPublicInterface param) {
        if (param instanceof YourPublicInterface.Internal) {
            // run the optimized code
        } else {
            // run the general code
        }
    }

}

Außerhalb des Pakets können Benutzer YourPublicInterface ohne Probleme verwenden.

In der allgemeinen Praxis erstellen Programmierer in ähnlichen Situationen abstrakte Klassen. In diesem Fall verlieren wir jedoch die Vorteile der Mehrfachvererbung.

1
Dávid Horváth

Das einzige Szenario, in dem es sinnvoll wäre, ist, wenn Sie die Sichtbarkeit auf dasselbe Paket beschränken möchten. Alle anderen Verwendungen von protected sind nicht anwendbar. Insbesondere werden protected-Methoden häufig verwendet, um Zugriff auf einige Details von Implementierungen auf unterer Ebene für Nachkommen zu erhalten. Aber zu erklären, dass in einer Schnittstelle kein Sinn besteht, da es keine Implementierung auf niedrigerer Ebene gibt.

Und selbst beim Paketszenario geht es nicht wirklich um Schnittstellen.

Um das zu erreichen, was Sie wahrscheinlich benötigen, benötigen Sie zwei Schnittstellen, eine für den internen Gebrauch und eine, die Sie in der öffentlichen API verfügbar machen. (Mit dem internen möglicherweise, aber nicht notwendigerweise, das öffentliche ausdehnen.) Oder, wie andere darauf hingewiesen haben, eine abstrakte Oberklasse.

1
biziclop

Gute Frage, wenn gefragt wurde, warum Entwickler Attribute der Benutzeroberfläche nicht geschützt gemacht haben, ...?

Das Erlauben von protected hätte gegen die Richtlinie/Eigenschaft der Schnittstelle verstoßen. "Unabhängig von der von Ihnen bereitgestellten Abstraktion sollten Sie überall ohne Bedingung verfügbar sein, sie jedoch nicht ändern können. (Beispiel: Wert der Instanz var)"

Um diese Art von Anwendungsfall zu bedienen, sollten Sie die Verwendung der Schnittstelle vermeiden.

0
user3234777

Schnittstellen sollen Methoden der Außenwelt aussetzen. Daher sind diese Methoden von Natur aus öffentlich. Wenn Sie jedoch Abstraktion innerhalb derselben Klassenfamilie einführen möchten, können Sie eine andere Abstraktionsebene zwischen Ihrer Schnittstelle und der Implementierungsklasse erstellen, d. H. Eine abstrakte Klasse. Ein Beispiel wird unten gezeigt.

public interface MyInterface {
    public void publicMethod(); // needs to be public
}

public abstract class MyAbstractClass implements MyInterface {
    @Override
    public void publicMethod() {
        protectedMethod(); // you can call protected method here
        // do other stuff
    }
    protected abstract void protectedMethod(); // can be protected
}

public class MyClass extends MyAbstractClass {
    @Override
    protected void protectedMethod() {
        // implement protected method here, without exposing it as public
    }
}
0
Stefanos Kargas