Warum gibt es in Java keinen Zugriffsmodifikator "Nur Unterklassen"?

16

In Java stehen vier Zugriffsmodifikatoren für Methoden zur Verfügung:

public - Jede Klasse kann diese Methode verwenden.

protected - Klassen in demselben Paket und Unterklassen in jedem Paket können diese Methode verwenden.

private - Nur diese Klasse kann diese Methode verwenden.

no modifier ("package private") - Nur Klassen im selben Paket können diese Methode verwenden.

Was häufig vorkommt, ist, dass ich nützliche Methoden in einer Oberklasse haben möchte, die alle Unterklassen verwenden können. Es wäre jedoch für andere Klassen nicht sinnvoll, auf diese Methode zuzugreifen, und in gewissem Sinne würde die Kapselung unterbrochen.

Also muss ich diese nützlichen Methoden in der Superklasse publicoder deklarieren protected, die sie allen anderen Klassen zumindest im Paket zur Verfügung stellt. Obwohl sie nur für die Unterklassen bestimmt sind.

Gibt es einen Grund, warum es subclasses-onlyin Java keinen Zugriffsmodifikator gibt ? Es kommt mir sehr merkwürdig vor. Vermisse ich etwas?

Ein subclasses-onlyZugriffsmodifikator ist auch nützlich, wenn Sie Variablen nur für Unterklassen verfügbar machen möchten. Was mir oft passiert.

Aviv Cohn
quelle

Antworten:

10

Weil Sie den Modifizierer " nur Unterklassen" emulieren können, indem Sie den Modifizierer " protected" verwenden und erzwingen, dass sich nur die übergeordnete Klasse und ihre Unterklassen im selben Paket befinden.

Dies ist in der Tat eine gute Praxis, da die Pakete nicht nur dazu beitragen, große Projekte im Hinblick auf den Zusammenhalt zu organisieren, sondern auch zeigen, dass die Klassen im selben Paket möglicherweise eine gewisse Kopplung aufweisen.

Tércio de Almeida
quelle
15
"und erzwingen, dass sich nur die Elternklasse und ihre Unterklassen im selben Paket befinden" - Wie würde man das nun tun ?!
JimmyB
1
Und dann können Sie den Zugriffsmodifikator "Nur Paket" nicht verwenden. Und du brauchst eine dumme Menge an Paketen. Dies ist keine praktische Lösung.
user253751
13

Java hatte ursprünglich einen solchen Modifikator. Es wurde geschrieben, private protectedaber in Java 1.0 entfernt.

Ich nehme an, das war ein Urteil, dass die zusätzliche Komplexität die Kosten nicht wert war.

Jedes Sprachmerkmal hat seine Kosten: es neuen Programmierern beizubringen; in der Dokumentation; bei der Implementierung in den Compiler-, JVM- und Dev-Tools; in Überlegungen zur Programmkorrektheit; bei der Einschränkung der zukünftigen Sprachentwicklung; und mehr. Sprachmerkmale interagieren miteinander, möglicherweise mit N 2 -Interaktionen.

Wie viel Prozent der Java-Programmierer haben die Java-Sprachspezifikation und die VM-Spezifikation gelesen? Ich wette, es ist ein kleiner Prozentsatz, der aus Gründen der Verständlichkeit und der technischen Produkte, auf die wir uns verlassen können, für eine noch einfachere Sprache plädiert

Der Vorteil der private protectedFunktion war gering, da das Paket die Haupteinheit der Modularität ist.

Jerry101
quelle
1
gab es also eine java version vor 1.0?
Mark Yisri
1
@MarkYisri Java hatte 1995 öffentliche Alpha- und Betaversionen und es wurde einiges an Code dagegen geschrieben.
David Moles
4

Die Zugriffskontrolle ist das Ergebnis einer Diskussion mit einem imaginären Entwickler, der mit Ihrer Klasse über die Klassenmethoden und -eigenschaften arbeitet.

SIE: Sagen Sie, Sie wollen x tun, Sie rufen die Methode doX auf. DEV: Erzählen Sie mir mehr. Was sind die Argumente?

Dies ist öffentlich ...

YOU: In doX rufe ich an ... DEV: Whoa, zu viele Informationen, das interessiert mich nicht. Ich möchte nur wissen, wie man es benutzt. Erzähl mir was anderes.

Das ist privat...

YOU: Wenn ich unterrichte, habe ich doX und doY, rufe doIt und das tut es. DEV: Ja, ich werde unterrichten, erzähl mir mehr ...

Dies ist geschützt ...

SIE: Ich fahre in einer Stunde in den Urlaub, die nächsten 6 Monate bin ich weg. Der Chef sagt, dieser Welpe gehört dir! Tschüss. DEV: Warte, geh noch nicht, erzähl mir alles ...

Das ist Paket.

YOU: Die Methode doItWhen wird nur von dieser Klasse aufgerufen und hat sich seit zehn Jahren nicht geändert. Es ... DEV: Oh, wir haben nur noch 50 Minuten. Nächste Eigenschaft, und schneller reden.

Dies ist privat geschützt ...

jmoreno
quelle
3

Das gibt es schon. Es ist geschützt.

Sie haben die Kontrolle darüber, welche Klassen im Paket vorhanden sind. Wenn das Paket keine andere Klasse enthält und eine bestimmte Variable oder Methode geschützt ist, handelt es sich um "nur Unterklassen".

Sie haben abermals die Kontrolle darüber, welche Klassen im Paket vorhanden sind. Sie können festlegen, dass die geschützten Methoden oder Variablen nicht verwendet werden.


quelle
3
Kann ich, abgesehen von bestimmten reservierten Systempaketen, keinem Paket eine Klasse hinzufügen, auch nicht einem von Ihnen, zu dem ich keine Klassen hinzufügen soll?
David Moles
@David IIRC ja, aber Sie können nicht von einer anderen JAR aus auf Paketfelder zugreifen. Selbst wenn Sie es in dasselbe Paket packen, können Sie nicht darauf zugreifen, wenn es sich in einer anderen JAR befindet. Wenn Sie sich jedoch auf dieselbe JAR-Datei beziehen, können Sie darauf zugreifen. Wenn Sie jedoch die betreffende JAR-Datei ändern können, können Sie den Zugriffsmodifikator genauso einfach ändern.
Pokechu22
1
@ Pokechu22 Ich denke, Sie müssen die JAR positiv besiegeln , um diesen Schutz zu erhalten, aber das ist ein guter Punkt.
David Moles