3696 Stimmen

Was ist der Unterschied zwischen public, protected, package-private und private in Java?

Gibt es in Java klare Regeln dafür, wann die einzelnen Zugriffsmodifikatoren zu verwenden sind, insbesondere die Standardeinstellung (package private), public , protected y private während der Herstellung class y interface und den Umgang mit dem Erbe?

6378voto

David Segonds Punkte 80975

Der offizielle Lehrgang kann für Sie von Nutzen sein.


Klasse

Paket

Unterklasse
(gleiche Packung)

Unterklasse
(diff pkg)

Welt

public

+

+

+

+

+

protected

+

+

+

+

kein Modifikator

+

+

+

private

+

+ : zugänglich
leer : nicht zugänglich

547voto

Schwern Punkte 138322

(Achtung: Ich bin kein Java-Programmierer, ich bin Perl-Programmierer. Perl hat keine formalen Schutzmechanismen, was vielleicht der Grund ist, warum ich das Problem so gut verstehe :) )

Privat

Wie man sich denken kann, sind nur die Klasse in dem sie erklärt wird, sehen kann.

Paket Privat

Sie kann nur von der Person gesehen und verwendet werden, die Paket in dem sie erklärt wurde. Dies ist der Standard in Java (was manche als Fehler ansehen).

Geschützt

Paket Private + kann von Unterklassen oder Paketmitgliedern eingesehen werden.

Öffentlich

Jeder kann es sehen.

Veröffentlicht

Sichtbar außerhalb des von mir kontrollierten Codes. (Dies ist zwar keine Java-Syntax, aber für diese Diskussion wichtig).

C++ definiert eine zusätzliche Ebene namens "Freund", und je weniger Sie darüber wissen, desto besser.

Wann sollten Sie was verwenden? Die ganze Idee ist die Kapselung, um Informationen zu verbergen. Sie wollen so weit wie möglich die Details, wie etwas gemacht wird, vor Ihren Benutzern verbergen. Und warum? Weil man sie dann später ändern kann, ohne den Code zu beschädigen. Auf diese Weise können Sie optimieren, refaktorisieren, umgestalten und Fehler beheben, ohne sich Sorgen machen zu müssen, dass jemand den Code verwendet, den Sie gerade überarbeitet haben.

Die Faustregel lautet also, die Dinge nur so sichtbar zu machen, wie sie sein müssen. Beginnen Sie mit privat und machen Sie nur so viel sichtbar wie nötig. Machen Sie nur das öffentlich, was der Benutzer wissen muss. Jedes Detail, das Sie öffentlich machen, schränkt Ihre Möglichkeiten ein, das System neu zu gestalten.

Wenn Sie möchten, dass die Benutzer das Verhalten anpassen können, ist es oft besser, die Interna in ein Objekt zu packen und diese Schnittstelle öffentlich zu machen, als sie öffentlich zu machen, damit sie überschrieben werden können. Auf diese Weise können sie einfach ein neues Objekt einfügen. Wenn Sie zum Beispiel einen CD-Player schreiben und die Funktion "Finde Informationen über diese CD" anpassen wollen, sollten Sie diese Methoden nicht öffentlich machen, sondern die gesamte Funktionalität in das Objekt packen und nur die Getter/Setter des Objekts öffentlich machen. Auf diese Weise fördert die Geiz-ist-geil-Methode eine gute Komposition und die Trennung von Belangen.

Ich bleibe bei "privat" und "öffentlich". Viele OO-Sprachen haben nur das. "Protected" kann praktisch sein, aber es ist eine Mogelpackung. Sobald eine Schnittstelle mehr als privat ist, entzieht sie sich Ihrer Kontrolle und Sie müssen im Code anderer Leute suchen, um Verwendungen zu finden.

Hier kommt die Idee der "Veröffentlichung" ins Spiel. Das Ändern einer Schnittstelle (Refactoring) erfordert, dass Sie den gesamten Code finden, der sie verwendet, und diesen ebenfalls ändern. Wenn die Schnittstelle privat ist, dann ist das kein Problem. Wenn sie geschützt ist, muss man alle Unterklassen finden. Wenn sie öffentlich ist, müssen Sie den gesamten Code finden, der Ihren Code verwendet. Manchmal ist das möglich, z.B. wenn Sie an einem Unternehmenscode arbeiten, der nur für den internen Gebrauch bestimmt ist, spielt es keine Rolle, ob eine Schnittstelle öffentlich ist. Sie können den gesamten Code aus dem Firmen-Repository nehmen. Aber wenn eine Schnittstelle "veröffentlicht" ist, wenn es Code gibt, der sie außerhalb Ihrer Kontrolle verwendet, dann sind Sie aufgeschmissen. Sie müssen diese Schnittstelle unterstützen oder riskieren, dass der Code beschädigt wird. Sogar geschützte Schnittstellen können als veröffentlicht betrachtet werden (weshalb ich mich nicht mit geschützten Schnittstellen beschäftige).

Viele Sprachen empfinden die hierarchische Einteilung in öffentlich/geschützt/privat als zu einschränkend und realitätsfern. Zu diesem Zweck gibt es das Konzept eines Eigenschaftsklasse aber das ist eine andere Show.

544voto

aioobe Punkte 397211

Hier ist eine bessere Version der Tabelle, die auch eine Spalte für Module enthält.

enter image description here


Erklärungen

  • A privat Mitglied ( i ) ist nur innerhalb derselben Klasse zugänglich, in der sie deklariert ist.

  • Ein Mitglied mit kein Zugriffsmodifikator ( j ) ist nur innerhalb von Klassen desselben Pakets zugänglich.

  • A geschützt Mitglied ( k ) ist in allen Klassen desselben Pakets zugänglich und innerhalb von Unterklassen in anderen Paketen.

  • A öffentlich Mitglied ( l ) ist für alle Klassen zugänglich (es sei denn, sie befindet sich in einer Modul die das Paket, in dem sie deklariert ist, nicht exportiert).


Welcher Modifikator ist zu wählen?

Zugriffsmodifikatoren sind ein Werkzeug, mit dem Sie verhindern können, dass die Kapselung versehentlich gebrochen wird. (*) . Fragen Sie sich, ob das Mitglied etwas sein soll, das klassen-, paket-, klassenhierarchieintern oder überhaupt nicht intern ist, und wählen Sie die Zugriffsebene entsprechend.

Beispiele:

  • Ein Feld long internalCounter sollte wahrscheinlich privat sein, da sie veränderbar und ein Implementierungsdetail ist.
  • Eine Klasse, die nur in einer Fabrikklasse (im selben Paket) instanziiert werden soll, sollte einen paketbeschränkten Konstruktor haben, da es nicht möglich sein sollte, ihn direkt von außerhalb des Pakets aufzurufen.
  • Eine interne void beforeRender() Methode, die unmittelbar vor dem Rendering aufgerufen und als Hook in Unterklassen verwendet wird, sollte geschützt werden.
  • A void saveGame(File dst) Methode, die aus dem GUI-Code aufgerufen wird, sollte öffentlich sein.

(*) Was genau ist Verkapselung?

230voto

Abdull Punkte 24487
____________________________________________________________________
                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |    
Modifier of x \ |               |           |               |       
————————————————*———————————————+———————————+———————————————+———————
public          |              |          |              |     
————————————————+———————————————+———————————+———————————————+———————
protected       |              |          |              |      
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |              |          |              |      
————————————————+———————————————+———————————+———————————————+———————
private         |              |          |              |       
____________________________________________________________________

178voto

John Nilsson Punkte 16587

Einfache Regel. Beginnen Sie damit, alles als privat zu deklarieren. Und gehen Sie dann zur Öffentlichkeit über, wenn der Bedarf besteht und das Design es rechtfertigt.

Bei der Darstellung von Mitgliedern sollten Sie sich fragen, ob es sich um Darstellungsentscheidungen oder Abstraktionsentscheidungen handelt. Ersteres sollten Sie vermeiden, da dies zu viele Abhängigkeiten von der tatsächlichen Darstellung und nicht von ihrem beobachtbaren Verhalten mit sich bringt.

In der Regel versuche ich zu vermeiden, Methodenimplementierungen durch Unterklassen zu überschreiben; es ist zu einfach, die Logik zu vermasseln. Deklarieren Sie abstrakte geschützte Methoden, wenn Sie beabsichtigen, dass sie überschrieben werden.

Verwenden Sie außerdem die @Override-Annotation beim Überschreiben, um zu verhindern, dass beim Refactoring etwas kaputt geht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X