Was ist der Unterschied zwischen öffentlich, geschützt, paketprivat und privat in Java?

3171

In Java gibt es klare Regeln auf , wenn jeder von Zugriffsmodifikatoren, nämlich den Standard (Paket privat) zu verwenden, public, protectedund private, während machen classund interfaceund dem Umgang mit Vererbung?

Intrepion
quelle
161
privateversteckt sich vor anderen Klassen im Paket. publicstellt Klassen außerhalb des Pakets zur Verfügung. protectedist eine Version von publicnur auf Unterklassen beschränkt.
Museful
87
@Tennenrishin - Nein; Im Gegensatz zu C ++ protectedmacht die Methode in Java auch vom gesamten Paket aus zugänglich. Diese Dummheit in Javas Sichtbarkeitsmodell bricht das Ziel von protected.
Nicolas Barbulesco
35
@Nicolas Es ist aus dem gesamten Paket zugänglich, mit oder ohne protected. Als Zugang Modifikator , alles , was protectedtut , ist zu Subklassen außerhalb des Pakets zu belichten.
Museful
15
@tennenrishin - nun, das hat Nicolas gesagt ... und du wiederholst es gerade. Was Sie ursprünglich gesagt haben, war, dass protected- und ich zitiere - "eine Version der Öffentlichkeit ist, die nur auf Unterklassen beschränkt ist", was nach Ihrer eigenen Zulassung nicht zutrifft, da protected auch den Zugriff über das gesamte Paket ermöglicht (ergo beschränkt es den Zugriff auf Unterklassen nicht. )
luis.espinal
10
Ich stimme Nicolas auch darin zu, dass der geschützte Zugriffsmodus in Java idiotisch ist. Was passiert ist, ist, dass Java horizontale (Gitter) und vertikale Zugriffsbeschränkungsqualifikatoren zusammengeführt hat. Der Standardbereich ist eine horizontale / Gitterbeschränkung, wobei das Gitter das Paket ist. Öffentlich ist eine weitere horizontale Einschränkung, bei der das Gitter die ganze Welt ist. Privat und (C ++) geschützt sind vertikal. Es wäre besser gewesen, wenn wir beispielsweise in protected-packageden seltenen Fällen, in denen wir ihn tatsächlich benötigten, einen Querschnittszugriff hätten, der protectedder C ++ - Version von protected entspricht.
Luis.espinal

Antworten:

5637

Das offizielle Tutorial kann für Sie von Nutzen sein.

______________________________________________________________
| │ Klasse │ Paket │ Unterklasse │ Unterklasse │ Welt |
| │ │ │ (gleiches Päckchen) │ (diff Pkg) │ |
| ────────────────────────────────────────────────── ──┼──────── |
| public │ + │ + │ + │ + │ + | 
| ────────────────────────────────────────────────── ──┼──────── |
| protected │ + │ + │ + │ + │ | 
| ────────────────────────────────────────────────── ──┼──────── |
| kein Modifikator│ + │ + │ + │ │ | 
| ────────────────────────────────────────────────── ──┼──────── |
| privat │ + │ │ │ │ |
| ___________ | _______ | _________ | __________ | __________ | ________ |
 +: zugänglich leer: nicht zugänglich
David Segonds
quelle
5
Die obige Tabelle ist falsch, da sogar privateMitglieder von jeder Klasse / statischen Methode in derselben Quelldatei gesehen / verwendet werden können.
Usagi Miyamoto
5
Auf das geschützte Mitglied kann nur von einer Unterklasse desselben Pakets zugegriffen werden, nicht jedoch von einer Unterklasse aus einem anderen Paket. Es sollte eine Korrektur in der obigen Tabelle geben
Niks
2
Die Welt ist in Ihrem Projekt . Ich sollte es weiter erklären. Bibliotheken befinden sich in Ihrem Projekt. Wenn Sie eine Bibliothek erstellen, werden diese öffentlichen Klassen und Methoden ebenfalls verfügbar gemacht. Nur innerhalb Ihres Projekts zu sagen, ist ein bisschen falsch. "Alles, was es benutzt" ist eine bessere Beschreibung.
Adprocas
3
Wenn ich zum Beispiel habe MyClassund mache, habe AnotherClass extends MyClassich von innen Zugriff auf alle geschützten und öffentlichen Methoden und Eigenschaften AnotherClass. Wenn ich MyClass myClass = new MyClass();in AnotherClassirgendwo - sagen wir mal den Konstruktor - ich nur Zugriff auf die öffentlichen Methoden haben wird , wenn es in einem anderen Paket. Beachten Sie, dass ich in diesem Fall = new MyClass() { @Override protected void protectedMethod() { //some logic } };anscheinend auf geschützte Methoden zugreifen kann, dies entspricht jedoch der Erweiterung, jedoch inline.
Adprocas
3
Leider ist diese Antwort eine grobe Vereinfachung. Die Realität ist etwas komplizierter, besonders wenn man bedenkt protected(was eigentlich ein ziemlich schwer zu verstehender Zugriffsmodifikator ist - die meisten Leute, die glauben zu wissen, was protectedbedeutet, tun das wirklich nicht). Wie Bohemian betonte, beantwortet es die Frage nicht - es sagt nichts darüber aus, wann jeder Zugriffsmodifikator verwendet werden soll. Meiner Meinung nach ist diese Antwort nicht ganz schlecht genug , um downvote, aber in der Nähe. Aber über 4000 Upvotes? Wie ist es passiert?
Dawood ibn Kareem
483

(Vorsichtsmaßnahme: Ich bin kein Java-Programmierer, ich bin ein Perl-Programmierer. Perl hat keinen formalen Schutz, weshalb ich das Problem vielleicht so gut verstehe :))

Privat

Wie Sie denken, kann es nur die Klasse sehen, in der es deklariert ist.

Paket privat

Es kann nur von dem Paket gesehen und verwendet werden , in dem es deklariert wurde. Dies ist die Standardeinstellung in Java (was einige als Fehler ansehen).

Geschützt

Package Private + kann von Unterklassen oder Paketmitgliedern gesehen werden.

Öffentlichkeit

Jeder kann es sehen.

Veröffentlicht

Sichtbar außerhalb des von mir kontrollierten Codes. (Obwohl dies keine Java-Syntax ist, ist es 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. So weit wie möglich möchten Sie die Details, wie etwas getan wird, vor Ihren Benutzern verbergen. Warum? Denn dann können Sie sie später ändern und den Code von niemandem beschädigen. Auf diese Weise können Sie Fehler optimieren, umgestalten, neu gestalten und beheben, ohne befürchten zu müssen, dass jemand den Code verwendet hat, den Sie gerade überarbeitet haben.

Als Faustregel gilt also, Dinge nur so sichtbar zu machen, wie sie sein müssen. Beginnen Sie mit privat und fügen Sie nur bei Bedarf mehr Sichtbarkeit hinzu. Machen Sie nur das öffentlich, was der Benutzer unbedingt wissen muss. Jedes Detail, das Sie öffentlich machen, verkrampft Ihre Fähigkeit, das System neu zu gestalten.

Wenn Sie möchten, dass Benutzer Verhaltensweisen anpassen können, anstatt Interna öffentlich zu machen, damit sie sie überschreiben können, ist es oft eine bessere Idee, diese Eingeweide in ein Objekt zu schieben und diese Schnittstelle öffentlich zu machen. Auf diese Weise können sie einfach ein neues Objekt einstecken. Wenn Sie beispielsweise einen CD-Player schreiben und möchten, dass das Bit "Informationen zu dieser CD suchen" anpassbar ist, anstatt diese Methoden öffentlich zu machen, würden Sie all diese Funktionen in ein eigenes Objekt einfügen und nur Ihren Objekt-Getter / Setter öffentlich machen . Auf diese Weise fördert das geizige Freilegen Ihrer Eingeweide eine gute Zusammensetzung und Trennung von Bedenken

Persönlich bleibe ich nur bei "privat" und "öffentlich". Viele OO-Sprachen haben genau das. "Geschützt" kann praktisch sein, aber es ist wirklich ein Betrug. Sobald eine Schnittstelle mehr als privat ist, liegt sie außerhalb Ihrer Kontrolle und Sie müssen im Code anderer Personen nach Verwendungsmöglichkeiten suchen.

Hier kommt die Idee von "veröffentlicht" ins Spiel. Um eine Schnittstelle zu ändern (umzugestalten), müssen Sie den gesamten Code finden, der sie verwendet, und dies auch ändern. Wenn die Schnittstelle privat ist, ist das kein Problem. Wenn es geschützt ist, müssen Sie alle Ihre Unterklassen suchen. Wenn es öffentlich ist, müssen Sie den gesamten Code suchen, der Ihren Code verwendet. Manchmal ist dies beispielsweise möglich, wenn Sie an Unternehmenscode arbeiten, der nur für den internen Gebrauch bestimmt ist. Dabei spielt es keine Rolle, ob eine Schnittstelle öffentlich ist. Sie können den gesamten Code aus dem Unternehmens-Repository abrufen. Wenn jedoch eine Schnittstelle "veröffentlicht" wird und Code außerhalb Ihrer Kontrolle verwendet wird, werden Sie abgespritzt. Sie müssen diese Schnittstelle unterstützen oder riskieren, Code zu brechen. Sogar geschützte Schnittstellen können als veröffentlicht betrachtet werden (weshalb ich nicht '

Viele Sprachen empfinden den hierarchischen Charakter von öffentlich / geschützt / privat als zu einschränkend und nicht im Einklang mit der Realität. Zu diesem Zweck gibt es das Konzept einer Merkmalsklasse , aber das ist eine andere Show.

Schwern
quelle
26
Freunde -> "Je weniger Sie darüber wissen, desto besser" ---> Es bietet selektive Sichtbarkeit, die der Privatsphäre von Paketen immer noch überlegen ist. In C ++ hat es seine Verwendung, da nicht alle Funktionen Mitgliedsfunktionen sein können und Freunde besser sind als das Veröffentlichen. Natürlich besteht die Gefahr des Missbrauchs durch böse Geister.
Sebastian Mach
30
Es sollte auch beachtet werden, dass "geschützt" in C ++ eine andere Bedeutung hat - eine geschützte Methode ist effektiv privat, kann aber dennoch von einer erbenden Klasse aufgerufen werden. (Im Gegensatz zu Java, wo es von jeder Klasse innerhalb desselben Pakets aufgerufen werden kann.)
Rhys van der Waerden
9
@RhysvanderWaerden C # ist in dieser Hinsicht dasselbe wie C ++. Ich finde es ziemlich seltsam, dass Java nicht zulässt, ein Mitglied zu deklarieren, auf das die Unterklasse zugreifen kann, aber nicht das gesamte Paket. Es ist irgendwie verkehrt herum für mich - ein Paket ist breiter gefasst als eine Kinderklasse!
Konrad Morawski
15
@KonradMorawski IMHO-Paket ist kleiner als Unterklasse. Wenn Sie Ihre Klasse nicht als endgültig deklariert haben, sollten Benutzer in der Lage sein, sie zu unterklassifizieren. Daher ist Java-geschützt Teil Ihrer veröffentlichten Benutzeroberfläche. OTOH, Pakete werden implizit von einer einzigen Organisation entwickelt: z. B. com.mycompany.mypackage. Wenn sich Ihr Code in meinem Paket deklariert, erklären Sie sich implizit als Teil meiner Organisation, sodass wir kommunizieren sollten. Daher wird das Paket für ein kleineres / leichter erreichbares Publikum (Personen in meinem Unternehmen) als die Unterklasse (Personen, die mein Objekt erweitern) veröffentlicht und zählt daher als geringere Sichtbarkeit.
Gleichnamiger
2
friendist gut für die Definition spezieller Beziehungen zwischen Klassen. Bei korrekter Verwendung ermöglicht es in vielen Fällen eine überlegene Kapselung. Beispielsweise kann es von einer privilegierten Factory-Klasse verwendet werden, um interne Abhängigkeiten in einen konstruierten Typ einzufügen. Es hat einen schlechten Ruf, weil Leute, denen es nicht wichtig ist, ein gut gestaltetes Objektmodell korrekt zu pflegen, es missbrauchen können, um ihre Arbeitsbelastung zu verringern.
Dennis
434

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

Java Access Modifiers

Erklärungen

  • Auf ein privates Mitglied ( i) kann nur innerhalb derselben Klasse zugegriffen werden, in der es deklariert ist.

  • Auf ein Mitglied ohne Zugriffsmodifikator ( j) kann nur innerhalb von Klassen im selben Paket zugegriffen werden.

  • Auf ein geschütztes Mitglied ( k) kann in allen Klassen im selben Paket und in Unterklassen in anderen Paketen zugegriffen werden.

  • Ein öffentliches Mitglied ( l) ist für alle Klassen zugänglich (es sei denn, es befindet sich in einem Modul , das das Paket, in dem es deklariert ist, nicht exportiert).


Welcher Modifikator soll gewählt werden?

Zugriffsmodifikatoren sind ein Tool, mit dem Sie verhindern können, dass die Kapselung versehentlich unterbrochen wird (*) . Fragen Sie sich, ob das Mitglied für die Klasse, das Paket, die Klassenhierarchie oder gar nicht intern sein soll, und wählen Sie die entsprechende Zugriffsebene aus.

Beispiele:

  • Ein Feld long internalCountersollte wahrscheinlich privat sein, da es veränderlich ist und ein Implementierungsdetail enthält.
  • Eine Klasse, die nur in einer Factory-Klasse (im selben Paket) instanziiert werden sollte, sollte einen Konstruktor mit eingeschränkten Paketen haben, da es nicht möglich sein sollte, sie direkt von außerhalb des Pakets aufzurufen.
  • Eine interne void beforeRender()Methode, die direkt vor dem Rendern aufgerufen und als Hook in Unterklassen verwendet wird, sollte geschützt werden.
  • Eine void saveGame(File dst)Methode, die vom GUI-Code aufgerufen wird, sollte öffentlich sein.

(*) Was genau ist Verkapselung?

aioobe
quelle
11
Ich sage nur: Es gibt viele Leute, die Probleme haben, rot / grüne Farben zu unterscheiden. Tabellen mit rot / grün (oder gelb / orange / ...) Farbschemata sind selten "besser"
;-)
1
@ GhostCat, ich bin anderer Meinung. Ich denke, Rot / Grün passt intuitiv zu "funktioniert" / "funktioniert nicht" für viele Menschen, dh es ist besser als viele Alternativen.
Aioobe
8
colourblindawareness.org/colour-blindness/… ... Die 8% der farbenblinden Männer können ungefähr in 1% Deuteranope, 1% Protanope, 1% Protanomale und 5% Deuteranomale unterteilt werden . Und da ich einer dieser 50% dieser 5% bin, seien Sie versichert: Rot / Grün ist scheiße.
GhostCat
6
@ GhostCat Ok .. das ist ein größerer Teil der Bevölkerung als ich erwartet hatte. Ich habe das Bild in diesen Farbenblindheitssimulator hochgeladen und alle verschiedenen Modi getestet. Selbst im Monochromie- / Achromatopsie-Modus ist der Farbunterschied angemessen. Kannst du den Unterschied sehen oder ist der Simulator ausgeschaltet? (Ich bin immer noch der Meinung, dass Rot / Grün für Menschen, die Farben sehen, sehr intuitiv ist.)
Aioobe
3
Ich kann den Unterschied erkennen, aber ich kann auch die Hälfte der Farbenblindheitstests bestehen, die wir in Deutschland für den Führerschein durchführen müssen ;-) ... aber ich denke, ein solcher Simulator ist "gut genug".
GhostCat
206
____________________________________________________________________
                | 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         |              |          |              |       
____________________________________________________________________
Abdull
quelle
1
Es lohnt sich, in Worte zu fassen: "Der geschützte Modifikator stellt das Objekt für andere Pakete zur Verfügung, während der Standard- / Nicht-Modifikator den Zugriff auf dasselbe Paket einschränkt"
vanguard69
2
@ vanguard69, der protectedModifikator stellt das markierte Objekt (Klasse, Methode oder Feld) einer anderen Klasse in einem anderen Paket nur dann zur Verfügung, wenn die andere Klasse eine Unterklasse der Klasse ist, in der das protectedmarkierte Objekt deklariert ist.
Abdull
"nicht untergetaucht"? "diese Unterklasse in einem anderen Paket"? Huh. Ich dachte, ich kenne Java.
sehe
@AlexanderFarber haben Sie für eine bestimmte Browserkonfiguration optimiert? Dies ist jetzt mein Chrom und dies ist Firefox
sehe
Hmm, lassen Sie uns dann mein Wechselgeld zurücksetzen
Alexander Farber
165

Einfache Regel. Beginnen Sie damit, alles für privat zu erklären. Und dann Fortschritte in Richtung Öffentlichkeit, wenn sich die Bedürfnisse ergeben und das Design dies rechtfertigt.

Wenn Sie Mitglieder verfügbar machen, fragen Sie sich, ob Sie Repräsentations- oder Abstraktionsoptionen verfügbar machen. Das erste ist etwas, das Sie vermeiden möchten, da es zu viele Abhängigkeiten von der tatsächlichen Darstellung und nicht von ihrem beobachtbaren Verhalten einführt.

In der Regel versuche ich, das Überschreiben von Methodenimplementierungen durch Unterklassen zu vermeiden. Es ist zu einfach, die Logik zu vermasseln. Deklarieren Sie abstrakte geschützte Methoden, wenn Sie beabsichtigen, diese zu überschreiben.

Verwenden Sie beim Überschreiben auch die Annotation @Override, um zu verhindern, dass beim Refactor Probleme auftreten.

John Nilsson
quelle
3
@RuchirBaronia, "world" = der gesamte Code in der Anwendung, unabhängig davon, wo er sich befindet.
Andrejs
116

Es ist tatsächlich etwas komplizierter als ein einfaches Raster zeigt. Das Raster zeigt an, ob ein Zugriff zulässig ist, aber was genau macht einen Zugriff aus? Außerdem interagieren Zugriffsebenen auf komplexe Weise mit verschachtelten Klassen und Vererbung.

Der "Standard" -Zugriff (angegeben durch das Fehlen eines Schlüsselworts) wird ebenfalls aufgerufen paketprivat bezeichnet . Ausnahme: In einer Schnittstelle bedeutet kein Modifikator öffentlichen Zugriff. Andere Modifikatoren als public sind verboten. Enum-Konstanten sind immer öffentlich.

Zusammenfassung

Ist ein Zugriff auf ein Mitglied mit diesem Zugriffsspezifizierer zulässig?

  • Mitglied ist private : Nur wenn Mitglied in derselben Klasse wie der aufrufende Code definiert ist.
  • Mitglied ist Paket privat: Nur wenn sich der aufrufende Code im unmittelbar umschließenden Paket des Mitglieds befindet.
  • Mitglied ist protected : Gleiches Paket oder wenn Mitglied in einer Oberklasse der Klasse definiert ist, die den aufrufenden Code enthält.
  • Mitglied ist public: Ja.

Welche Zugriffsspezifizierer gelten für

Lokale Variablen und formale Parameter können keine Zugriffsspezifizierer annehmen. Da sie nach den Regeln des Geltungsbereichs von Natur aus nicht von außen zugänglich sind, sind sie praktisch privat.

Für Klassen im oberen Bereich sind nur publicund package-private zulässig. Diese Designwahl liegt vermutlich daran , protectedund privatewürde auf Paketebene redundant sein (es gibt keine Vererbung von Paketen).

Alle Zugriffsspezifizierer sind für Klassenmitglieder möglich (Konstruktoren, Methoden und statische Elementfunktionen, verschachtelte Klassen).

Verwandte: Java Class Accessibility

Auftrag

Die Zugriffsspezifizierer können streng bestellt werden

public> protected> package-private> private

was bedeutet, dass publicder meiste Zugang bietet,private den geringsten. Jede mögliche Referenz für ein privates Mitglied gilt auch für ein paketprivates Mitglied. Jeder Verweis auf ein paketprivates Mitglied gilt für ein geschütztes Mitglied usw. (Der Zugriff auf geschützte Mitglieder für andere Klassen im selben Paket wurde als Fehler angesehen.)

Anmerkungen

  • Ein Verfahren der Klasse sind erlaubt auf private Mitglieder anderer Objekte derselben Klasse zugreifen. Genauer gesagt kann eine Methode der Klasse C auf private Mitglieder von C für Objekte einer beliebigen Unterklasse von C zugreifen. Java unterstützt nicht die Einschränkung des Zugriffs nach Instanzen, sondern nur nach Klassen. (Vergleiche mit Scala, die es mit unterstützt private[this].)
  • Sie benötigen Zugriff auf einen Konstruktor, um ein Objekt zu erstellen. Wenn also alle Konstruktoren privat sind, kann die Klasse nur durch Code erstellt werden, der in der Klasse lebt (normalerweise statische Factory-Methoden oder statische Variableninitialisierer). Ähnliches gilt für paketprivate oder geschützte Konstruktoren.
    • Nur private Konstruktoren zu haben bedeutet auch, dass die Klasse nicht extern in Unterklassen unterteilt werden kann, da Java erfordert, dass die Konstruktoren einer Unterklasse implizit oder explizit einen Konstruktor der Oberklasse aufrufen. (Es kann jedoch eine verschachtelte Klasse enthalten, die es in Unterklassen unterteilt.)

Innere Klassen

Sie müssen auch verschachtelte Bereiche berücksichtigen , z. B. innere Klassen. Ein Beispiel für die Komplexität ist, dass innere Klassen Mitglieder haben, die selbst Zugriffsmodifikatoren verwenden können. Sie können also eine private innere Klasse mit einem öffentlichen Mitglied haben; Kann auf das Mitglied zugegriffen werden? (Siehe unten.) Die allgemeine Regel besteht darin, den Umfang zu betrachten und rekursiv zu überlegen, ob Sie auf jede Ebene zugreifen können.

Dies ist jedoch recht kompliziert. Ausführliche Informationen finden Sie in der Java-Sprachspezifikation . (Ja, in der Vergangenheit gab es Compiler-Fehler.)

Betrachten Sie dieses Beispiel, um einen Eindruck davon zu bekommen, wie diese interagieren. Es ist möglich, private innere Klassen zu "lecken"; Dies ist normalerweise eine Warnung:

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}

Compiler-Ausgabe:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error

Einige verwandte Fragen:

Mechanische Schnecke
quelle
1
"Andere Modifikatoren als public sind verboten" - ab Java 9 ist dies nicht mehr der Fall: Schnittstellen können auch private Methoden haben.
MC Emperor
96

Als Faustregel gilt:

  • private: Klassenumfang.
  • default(oder package-private): Paketumfang.
  • protected: package scope + child(wie Paket, aber wir können es von verschiedenen Paketen unterordnen). Der geschützte Modifikator behält immer die "Eltern-Kind" -Beziehung bei.
  • public: überall.

Wenn wir also das Zugriffsrecht in drei Rechte aufteilen:

  • (D) irect (Aufruf von einer Methode innerhalb derselben Klasse oder über "diese" Syntax).
  • (R) Referenz (Aufruf einer Methode unter Verwendung eines Verweises auf die Klasse oder über die "Punkt" -Syntax).
  • (I) Vererbung (über Unterklassen).

dann haben wir diese einfache Tabelle:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+
nxhoaf
quelle
54

Kurz gesagt

  • public: von überall zugänglich.
  • protected: Zugriff auf die Klassen desselben Pakets und die in einem beliebigen Paket befindlichen Unterklassen.
  • Standard (kein Modifikator angegeben): Zugriff auf die Klassen desselben Pakets.
  • private: nur innerhalb derselben Klasse zugänglich.
Ravi
quelle
48

Der am meisten missverstandene Zugriffsmodifikator in Java ist protected. Wir wissen, dass es dem Standardmodifikator ähnlich ist, mit einer Ausnahme, in der Unterklassen es sehen können. Aber wie? Hier ist ein Beispiel, das hoffentlich die Verwirrung verdeutlicht:

  • Angenommen, wir haben 2 Klassen; Fatherund Sonjedes in einem eigenen Paket:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
  • Lassen Sie uns eine geschützte Methode hinzufügen foo()zu Father.

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
  • Die Methode foo()kann in 4 Kontexten aufgerufen werden:

    1. Innerhalb einer Klasse, die sich in demselben Paket foo()befindet, in dem definiert ist ( fatherpackage):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
    2. Innerhalb einer Unterklasse auf der aktuellen Instanz über thisoder super:

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
    3. Auf einer Referenz, deren Typ dieselbe Klasse ist:

      package fatherpackage;
      
      public class Father
      {
          public void fatherMethod(Father f)
          {
              f.foo(); // valid even if foo() is private
          }
      }
      
      -------------------------------------------
      
      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Son s)
          {
              s.foo();
          }
      }
    4. Auf einer Referenz, deren Typ die übergeordnete Klasse ist und die sich in dem Paket foo()befindet, in dem definiert ist ( fatherpackage) [Dies kann in Kontext-Nr. 1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
  • Die folgenden Situationen sind ungültig.

    1. Auf einer Referenz, deren Typ die übergeordnete Klasse ist und die sich außerhalb des Pakets foo()befindet, in dem definiert ist ( fatherpackage):

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
    2. Eine Nicht-Unterklasse innerhalb eines Pakets einer Unterklasse (Eine Unterklasse erbt die geschützten Mitglieder von ihrem übergeordneten Element und macht sie für Nicht-Unterklassen privat):

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }
Eng.Fouad
quelle
Object#clone()ist ein Beispiel für ein protectedMitglied.
Eng.Fouad
Was ist der Unterschied zwischen dem Tun super.foo()und der ersten ungültigen Situation f.foo()?
cst1992
1
@ cst1992 Es ist verwirrend, aber siehe Java-Sprachspezifikation 6.6.2: "Auf ein geschütztes Mitglied oder einen Konstruktor eines Objekts kann von außerhalb des Pakets zugegriffen werden, in dem es nur durch Code deklariert ist, der für die Implementierung dieses Objekts verantwortlich ist." Bei super.foo () ist die Referenz "super" "direkt für die Implementierung verantwortlich", die Referenz "f" jedoch nicht. Warum? Weil Sie zu 100% sicher sein können, dass "super" vom Typ Vater ist, aber nicht für "f"; Zur Laufzeit könnte es sich um einen anderen Untertyp des Vaters handeln. Siehe docs.oracle.com/javase/specs/jls/se9/html/…
Skomisa
1
Es ist erfrischend, eine Antwort von jemandem zu lesen, der versteht protected. Leider machen alle anderen Antworten auf dieser Seite, die protectedsie definieren , etwas falsch.
Dawood ibn Kareem
30

Privat

  • Methoden, Variablen und Konstruktoren

Auf Methoden, Variablen und Konstruktoren, die als privat deklariert sind, kann nur innerhalb der deklarierten Klasse selbst zugegriffen werden.

  • Klasse und Schnittstelle

Der Modifikator für privaten Zugriff ist die restriktivste Zugriffsebene. Klasse und Schnittstellen können nicht privat sein.

Hinweis

Auf Variablen, die als privat deklariert sind, kann außerhalb der Klasse zugegriffen werden, wenn in der Klasse öffentliche Getter-Methoden vorhanden sind. Auf Variablen, Methoden und Konstruktoren, die in einer Oberklasse als geschützt deklariert sind, kann nur von den Unterklassen in einem anderen Paket oder einer Klasse innerhalb des Pakets der Klasse der geschützten Mitglieder zugegriffen werden.


Geschützt

  • Klasse und Schnittstelle

Der Modifikator für geschützten Zugriff kann nicht auf Klassen und Schnittstellen angewendet werden.

Methoden, Felder können als geschützt deklariert werden, Methoden und Felder in einer Schnittstelle können jedoch nicht als geschützt deklariert werden.

Hinweis

Durch den geschützten Zugriff kann die Unterklasse die Hilfsmethode oder -variable verwenden und gleichzeitig verhindern, dass eine nicht verwandte Klasse versucht, sie zu verwenden.


Öffentlichkeit

Auf eine als öffentlich deklarierte Klasse, Methode, Konstruktor, Schnittstelle usw. kann von jeder anderen Klasse aus zugegriffen werden.

Daher kann auf Felder, Methoden und Blöcke, die in einer öffentlichen Klasse deklariert sind, von jeder Klasse aus zugegriffen werden, die zum Java-Universum gehört.

  • Verschiedene Pakete

Wenn sich die öffentliche Klasse, auf die wir zugreifen möchten, in einem anderen Paket befindet, muss die öffentliche Klasse dennoch importiert werden.

Aufgrund der Klassenvererbung werden alle öffentlichen Methoden und Variablen einer Klasse von ihren Unterklassen geerbt.


Standard -Nein Schlüsselwort:

Standardzugriffsmodifikator bedeutet, dass wir keinen Zugriffsmodifikator für eine Klasse, ein Feld, eine Methode usw. explizit deklarieren.

  • Innerhalb der gleichen Pakete

Eine Variable oder Methode, die ohne Zugriffssteuerungsmodifikator deklariert wurde, steht jeder anderen Klasse im selben Paket zur Verfügung. Die Felder in einer Schnittstelle sind implizit public static final und die Methoden in einer Schnittstelle sind standardmäßig public.

Hinweis

Wir können die statischen Felder nicht überschreiben. Wenn Sie versuchen, sie zu überschreiben, wird kein Fehler angezeigt, aber es funktioniert nicht, was wir außer.

Verwandte Antworten

Verweise auf Links

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html http://www.tutorialspoint.com/java/java_access_modifiers.htm

Nambi
quelle
21

Der Unterschied liegt in den bereits bereitgestellten Links, aber welche zu verwenden sind, hängt normalerweise vom "Prinzip des geringsten Wissens" ab. Lassen Sie nur die geringste Sichtbarkeit zu, die benötigt wird.

Joe Phillips
quelle
20

Privat : Nur eingeschränkter Zugang zur Klasse

Standard (kein Modifikator) : Eingeschränkter Zugriff auf Klasse und Paket

Geschützt : Eingeschränkter Zugriff auf Klassen, Pakete und Unterklassen (sowohl innerhalb als auch außerhalb des Pakets)

Öffentlich : Zugänglich für Klassen, Pakete (alle) und Unterklassen ... Kurz gesagt, überall.

Samkit Shah
quelle
17

Zugriffsmodifikatoren dienen dazu, den Zugriff auf mehreren Ebenen einzuschränken.

Öffentlich: Es ist im Grunde so einfach, wie Sie von jeder Klasse aus darauf zugreifen können, ob diese im selben Paket enthalten ist oder nicht.

Um darauf zuzugreifen, wenn Sie sich in demselben Paket befinden, können Sie direkt darauf zugreifen. Wenn Sie sich jedoch in einem anderen Paket befinden, können Sie ein Objekt der Klasse erstellen.

Standard: Auf dasselbe Paket kann von jeder Paketklasse aus zugegriffen werden.

Für den Zugriff können Sie ein Objekt der Klasse erstellen. Sie können jedoch nicht außerhalb des Pakets auf diese Variable zugreifen.

Geschützt: Sie können auf Variablen im selben Paket sowie auf Unterklassen in jedem anderen Paket zugreifen. so im Grunde ist es Standard + Vererbtes Verhalten.

Um auf ein in der Basisklasse definiertes geschütztes Feld zuzugreifen, können Sie ein Objekt der untergeordneten Klasse erstellen.

Privat: Es kann in derselben Klasse zugegriffen werden.

Bei nicht statischen Methoden können Sie aufgrund dieser Referenz direkt zugreifen (auch bei Konstruktoren). Um jedoch bei statischen Methoden darauf zugreifen zu können, müssen Sie ein Objekt der Klasse erstellen.

Prashant
quelle
16

Zugriffsmodifikatoren in Java.

Java-Zugriffsmodifikatoren werden verwendet, um die Zugriffssteuerung in Java bereitzustellen.

1. Standard:

Nur für die Klassen im selben Paket zugänglich.

Zum Beispiel,

// Saved in file A.java
package pack;

class A{
  void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B{
  public static void main(String args[]){
   A obj = new A(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}

Dieser Zugang ist eingeschränkter als öffentlich und geschützt, aber weniger eingeschränkt als privat.

2. Öffentlich

Kann von überall zugegriffen werden. (Globaler Zugang)

Zum Beispiel,

// Saved in file A.java

package pack;
public class A{
  public void msg(){System.out.println("Hello");}
}

// Saved in file B.java

package mypack;
import pack.*;

class B{
  public static void main(String args[]){
    A obj = new A();
    obj.msg();
  }
}

Ausgabe: Hallo

3. Privat

Nur innerhalb derselben Klasse zugänglich.

Wenn Sie versuchen, auf private Mitglieder einer Klasse in einer anderen zuzugreifen, wird ein Kompilierungsfehler ausgegeben. Zum Beispiel,

class A{
  private int data = 40;
  private void msg(){System.out.println("Hello java");}
}

public class Simple{
  public static void main(String args[]){
    A obj = new A();
    System.out.println(obj.data); // Compile Time Error
    obj.msg(); // Compile Time Error
  }
}

4. Geschützt

Nur für die Klassen im selben Paket und für die Unterklassen zugänglich

Zum Beispiel,

// Saved in file A.java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}

Ausgabe: Hallo

Geben Sie hier die Bildbeschreibung ein

Affy
quelle
14
  • öffentlich - von überall in der Anwendung zugänglich.

  • Standard - Zugriff vom Paket.

  • protected - Zugriff über Pakete und Unterklassen in anderen Paketen. auch

  • privat - nur von seiner Klasse zugänglich.

Shailendra Singh
quelle
14

Sichtbar für das Paket. Der Standard. Es werden keine Modifikatoren benötigt.

Nur für die Klasse sichtbar ( privat ).

Sichtbar für die Welt ( öffentlich ).

Sichtbar für das Paket und alle Unterklassen ( geschützt ).

Variablen und Methoden können ohne aufgerufene Modifikatoren deklariert werden. Standardbeispiele:

String name = "john";

public int age(){
    return age;
}

Modifikator für privaten Zugriff - privat:

Auf Methoden, Variablen und Konstruktoren, die als privat deklariert sind, kann nur innerhalb der deklarierten Klasse selbst zugegriffen werden. Der Modifikator für den privaten Zugriff ist die restriktivste Zugriffsebene. Klasse und Schnittstellen können nicht privat sein.

Auf Variablen, die als privat deklariert sind, kann außerhalb der Klasse zugegriffen werden, wenn in der Klasse öffentliche Getter-Methoden vorhanden sind.

Die Verwendung des privaten Modifikators ist die Hauptmethode, mit der sich ein Objekt selbst einkapselt und Daten vor der Außenwelt verbirgt.

Beispiele:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

Modifikator für den öffentlichen Zugriff - öffentlich:

Auf eine als öffentlich deklarierte Klasse, Methode, Konstruktor, Schnittstelle usw. kann von jeder anderen Klasse aus zugegriffen werden. Daher kann auf Felder, Methoden und Blöcke, die in einer öffentlichen Klasse deklariert sind, von jeder Klasse aus zugegriffen werden, die zum Java-Universum gehört.

Wenn sich die öffentliche Klasse, auf die wir zugreifen möchten, in einem anderen Paket befindet, muss die öffentliche Klasse dennoch importiert werden.

Aufgrund der Klassenvererbung werden alle öffentlichen Methoden und Variablen einer Klasse von ihren Unterklassen geerbt.

Beispiel:

public void cal(){

}

Modifikator für geschützten Zugriff - geschützt:

Auf Variablen, Methoden und Konstruktoren, die in einer Oberklasse als geschützt deklariert sind, kann nur von den Unterklassen in einem anderen Paket oder einer beliebigen Klasse innerhalb des Pakets der Klasse der geschützten Mitglieder zugegriffen werden.

Der Modifikator für geschützten Zugriff kann nicht auf Klassen und Schnittstellen angewendet werden. Methoden, Felder können als geschützt deklariert werden, Methoden und Felder in einer Schnittstelle können jedoch nicht als geschützt deklariert werden.

Durch den geschützten Zugriff kann die Unterklasse die Hilfsmethode oder -variable verwenden und gleichzeitig verhindern, dass eine nicht verwandte Klasse versucht, sie zu verwenden.

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}
Amila Isura
quelle
12

Diese Seite beschreibt gut den Modifikator für geschützten und Standardzugriff

.... Geschützt: Der geschützte Zugriffsmodifikator ist etwas knifflig und kann als Obermenge des Standardzugriffsmodifikators bezeichnet werden. Geschützte Mitglieder sind hinsichtlich des Zugriffs auf dasselbe Paket dieselben wie die Standardmitglieder. Der Unterschied besteht darin, dass die geschützten Mitglieder auch für die Unterklassen der Klasse zugänglich sind, in der das Mitglied deklariert ist und die sich außerhalb des Pakets befinden, in dem die übergeordnete Klasse vorhanden ist.

Diese geschützten Mitglieder sind jedoch „nur durch Vererbung außerhalb des Pakets zugänglich“. Das heißt, Sie können direkt auf ein geschütztes Mitglied einer Klasse in ihrer Unterklasse zugreifen, das in einem anderen Paket vorhanden ist, als ob das Mitglied in der Unterklasse selbst vorhanden wäre. Auf dieses geschützte Mitglied kann jedoch in der Unterklasse außerhalb des Pakets nicht über die Referenz der übergeordneten Klasse zugegriffen werden. ....

dameng
quelle
Nur um dies hinzuzufügen "Sobald das Kind Zugriff auf das geschützte Mitglied der Elternklasse erhält, wird es privat (oder besser gesagt ein spezielles privates Mitglied, das von den Unterklassen der Unterklasse geerbt werden kann) Mitglied der Unterklasse."
Anand
9

Davids Antwort liefert die Bedeutung jedes Zugriffsmodifikators. Ich würde vorschlagen, alle Klassen und Methoden jeder Klasse, die für den externen Gebrauch bestimmt sind (API), und alles andere privat zu veröffentlichen.

Mit der Zeit werden Sie ein Gefühl dafür entwickeln, wann einige Klassen paketprivat gemacht werden müssen und wann bestimmte Methoden für die Verwendung in Unterklassen als geschützt deklariert werden müssen.

Dov Wasserman
quelle
6

Hinweis: Dies ist nur eine Ergänzung zur akzeptierten Antwort.

Dies hängt mit Java Access Modifiers zusammen .

Von Java Access Modifiers :

Ein Java-Zugriffsmodifikator gibt an, welche Klassen auf eine bestimmte Klasse und ihre Felder, Konstruktoren und Methoden zugreifen können. Zugriffsmodifikatoren können für eine Klasse, ihre Konstruktoren, Felder und Methoden separat angegeben werden. Java-Zugriffsmodifikatoren werden in der täglichen Sprache manchmal auch als Java-Zugriffsspezifizierer bezeichnet, aber der richtige Name lautet Java-Zugriffsmodifikatoren. Klassen, Felder, Konstruktoren und Methoden können einen von vier verschiedenen Java-Zugriffsmodifikatoren haben:

  • Listenpunkt
  • Privat
  • Standard (Paket)
  • geschützt
  • Öffentlichkeit

Von der Kontrolle des Zugriffs auf Mitglieder einer Klasse Tutorials:

Zugriffsebenenmodifikatoren bestimmen, ob andere Klassen ein bestimmtes Feld verwenden oder eine bestimmte Methode aufrufen können. Es gibt zwei Ebenen der Zugriffskontrolle:

  • Auf der obersten Ebene - öffentlich oder paketprivat (kein expliziter Modifikator).
  • Auf Mitgliedsebene - öffentlich, privat, geschützt oder paketprivat (kein expliziter Modifikator).

Eine Klasse kann mit dem Modifikator public deklariert werden. In diesem Fall ist diese Klasse für alle Klassen überall sichtbar. Wenn eine Klasse keinen Modifikator hat (der Standard, auch als package-private bezeichnet), ist sie nur in ihrem eigenen Paket sichtbar

Die folgende Tabelle zeigt den Zugriff auf Mitglieder, die von jedem Modifikator zugelassen werden.

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
 Modifier     Class  Package  Subclass  World 
╠═════════════╬═══════╬═════════╬══════════╬═══════╣
 public       Y      Y        Y         Y     
 protected    Y      Y        Y         N     
 no modifier  Y      Y        N         N     
 private      Y      N        N         N     
╚═════════════╩═══════╩═════════╩══════════╩═══════╝

Die erste Datenspalte gibt an, ob die Klasse selbst Zugriff auf das durch die Zugriffsebene definierte Mitglied hat. Wie Sie sehen, hat eine Klasse immer Zugriff auf ihre eigenen Mitglieder. In der zweiten Spalte wird angegeben, ob Klassen im selben Paket wie die Klasse (unabhängig von ihrer Abstammung) Zugriff auf das Mitglied haben. Die dritte Spalte gibt an, ob Unterklassen der außerhalb dieses Pakets deklarierten Klasse Zugriff auf das Mitglied haben. Die vierte Spalte gibt an, ob alle Klassen Zugriff auf das Mitglied haben.

Zugriffsebenen wirken sich auf zwei Arten auf Sie aus. Wenn Sie Klassen verwenden, die aus einer anderen Quelle stammen, z. B. die Klassen in der Java-Plattform, bestimmen die Zugriffsebenen zunächst, welche Mitglieder dieser Klassen Ihre eigenen Klassen verwenden können. Zweitens müssen Sie beim Schreiben einer Klasse entscheiden, welche Zugriffsebene jede Mitgliedsvariable und jede Methode in Ihrer Klasse haben soll.

ישו אוהב אותך
quelle
1
Was genau ist die Ergänzung und warum wird der vorhandene Beitrag nicht bearbeitet?
sehe
Die Ergänzung ist Access Modifiers. Warum nicht bearbeiten? Die akzeptierte Antwort aus historischen Gründen unverändert zu lassen und meine Antwort zu geben.
18 אוהב אותך
5

Public Protected Default und Private sind Zugriffsmodifikatoren.

Sie dienen zum Einkapseln oder zum Ausblenden und Anzeigen von Inhalten der Klasse.

  1. Die Klasse kann öffentlich oder standardmäßig sein
  2. Klassenmitglieder können öffentlich, geschützt, standardmäßig oder privat sein.

Privat ist außerhalb der Klasse nicht zugänglich. Standard ist nur im Paket zugänglich. Geschützt im Paket sowie in jeder Klasse, die es erweitert. Die Öffentlichkeit ist offen für alle.

Normalerweise werden Mitgliedsvariablen als privat definiert, aber Mitgliedsmethoden sind öffentlich.

richa_v
quelle
Defaultist kein Zugriffsmodifikator, und zwei der anderen sind falsch geschrieben.
user207421
5

Oft habe ich festgestellt, dass das Erinnern an die Grundkonzepte jeder Sprache durch die Erstellung realer Analogien möglich wird. Hier ist meine Analogie zum Verständnis von Zugriffsmodifikatoren in Java:

Nehmen wir an, Sie sind Student an einer Universität und haben einen Freund, der Sie über das Wochenende besucht. Angenommen, es gibt eine große Statue des Universitätsgründers in der Mitte des Campus.

  • Wenn Sie ihn auf den Campus bringen, sehen Sie und Ihr Freund als erstes diese Statue. Dies bedeutet, dass jeder, der auf dem Campus spazieren geht, die Statue ohne Erlaubnis der Universität besichtigen kann. Dies macht die Statue als ÖFFENTLICH .

  • Als nächstes möchten Sie Ihren Freund in Ihr Wohnheim bringen, aber dafür müssen Sie ihn als Besucher registrieren. Dies bedeutet, dass er einen Zugangspass (der mit Ihrem identisch ist) erhält, um in verschiedene Gebäude auf dem Campus zu gelangen. Dies würde seine Zugangskarte als GESCHÜTZT machen .

  • Ihr Freund möchte sich beim WLAN auf dem Campus anmelden, verfügt jedoch nicht über die erforderlichen Anmeldeinformationen. Der einzige Weg, wie er online gehen kann, ist, wenn Sie Ihr Login mit ihm teilen. (Denken Sie daran, dass jeder Student, der an die Universität geht, auch über diese Anmeldeinformationen verfügt.) Dies würde Ihre Anmeldeinformationen als NO MODIFIER machen .

  • Schließlich möchte Ihr Freund Ihren Fortschrittsbericht für das Semester lesen, der auf der Website veröffentlicht ist. Jeder Student hat jedoch sein eigenes persönliches Login, um auf diesen Bereich der Campus-Website zuzugreifen. Dies würde diese Anmeldeinformationen als PRIVAT machen .

Hoffe das hilft!

Gieriger Codierer
quelle
4

Wenn Sie an Zugriffsmodifikatoren denken, denken Sie einfach so (gilt sowohl für Variablen als auch für Methoden ):

public-> von jedem Ort aus zugänglich
private-> nur innerhalb derselben Klasse zugänglich, in der es deklariert ist

Jetzt entsteht die Verwirrung, wenn es um defaultund gehtprotected

default-> Es ist kein Schlüsselwort für den Zugriffsmodifikator vorhanden. Dies bedeutet, dass es ausschließlich im Paket der Klasse verfügbar ist. Nirgendwo außerhalb dieses Pakets kann darauf zugegriffen werden.

protected-> Etwas weniger streng als defaultund abgesehen von denselben Paketklassen, auf die Unterklassen außerhalb des deklarierten Pakets zugreifen können.

Pritam Banerjee
quelle
4

Der Java-Zugriff ändert, welche Sie verwenden können

Geben Sie hier die Bildbeschreibung ein

Zugriffsmodifikator kann anwendbar sein class, field[Über] , method. Versuchen Sie, darauf zuzugreifen, eine Unterklasse zu erstellen oder diese zu überschreiben.

  • Zugang zu fieldoder methodüber a class.
  • Erbe. Der classZugriffsmodifikator für Nachfolger (Unterklassen) kann ein beliebiger sein. Der methodZugriffsmodifikator für Nachfolger (Überschreiben) sollte identisch sein oder ihn erweitern

Top Level Klasse (First Level Scope) kann publicund sein default. Nested class[Über] kann jeden von ihnen haben

package gilt nicht für die Pakethierarchie

Swift Access Modifikatoren

yoAlex5
quelle
2

Es geht nur um Kapselung (oder, wie Joe Phillips sagte, um geringstes Wissen ).

Beginnen Sie mit den restriktivsten (privaten) und prüfen Sie später, ob Sie weniger restriktive Modifikatoren benötigen.

Wir alle verwenden Methoden- und Mitgliedsmodifikatoren wie privat, öffentlich, ... aber eine Sache, die zu wenige Entwickler tun, ist die Verwendung von Paketen zum Organisieren Code logisch .

Beispiel: Sie können vertrauliche Sicherheitsmethoden in ein Sicherheitspaket einfügen. Fügen Sie dann eine öffentliche Klasse ein, die auf einen Teil des sicherheitsrelevanten Codes in diesem Paket zugreift, andere Sicherheitsklassen jedoch privat hält . Daher können andere Entwickler die öffentlich verfügbare Klasse nur von außerhalb dieses Pakets verwenden (es sei denn, sie ändern den Modifikator). Dies ist keine Sicherheitsfunktion, dient jedoch als Leitfaden für die Verwendung.

Outside world -> Package (SecurityEntryClass ---> Package private classes)

Eine andere Sache ist, dass Klassen, die stark voneinander abhängen, möglicherweise im selben Paket landen und möglicherweise überarbeitet oder zusammengeführt werden, wenn die Abhängigkeit zu stark ist.

Wenn Sie im Gegenteil alles als öffentlich festlegen , ist nicht klar, auf was zugegriffen werden soll oder nicht, was dazu führen kann, dass viel Javadoc geschrieben wird (was über den Compiler nichts erzwingt ...).

Christophe Roussy
quelle
2

privat-geschützte-öffentliche-perfekte-Analogie-für-die-variablen-Datentypen

Nach Blockdiagramm erläutert , wie Datenelemente der Basisklasse sind geerbt , wenn abgeleitete Klasse Zugriffsmodus ist privat .

Geben Sie hier die Bildbeschreibung ein

Hinweis: Das Deklarieren von Datenelementen mit einem privaten Zugriffsspezifizierer wird als Ausblenden von Daten bezeichnet.

Quelle: Zugriffsspezifizierer - privat, öffentlich und geschützt

leonidaa
quelle
1
Die Frage betraf Java, nicht C ++.
Benoit
1
@ Benoit Aber was ich gepostet habe, die Bilder im Special, sind nicht für beide gleich: Java und C ++? Diese Regeln gelten nicht auch für Java? danke
leonidaa
2
In C ++ gibt es nur 3 Modifikatoren, während es in Java 4 gibt.
Benoit
1
Die Analogie ist gut, aber der Standardzugriffsspezifizierer fehlt
mss
1
OP stellte die Frage "Was ist der Unterschied zwischen öffentlich, geschützt, paketprivat und privat in Java?"
JL_SO
2

Meine zwei Cent :)

Privat:

Klasse -> Eine Klasse der obersten Ebene kann nicht privat sein. innere Klassen können privat sein, auf die von derselben Klasse aus zugegriffen werden kann.

Instanzvariable -> nur in der Klasse zugänglich. Kein Zugriff außerhalb der Klasse möglich.

Paket-privat:

Klasse -> Eine Klasse der obersten Ebene kann paketprivat sein. Es kann nur von demselben Paket aus zugegriffen werden. Nicht vom Unterpaket, nicht vom externen Paket.

Instanzvariable -> Zugriff über dasselbe Paket. Nicht vom Unterpaket, nicht vom externen Paket.

geschützt:

Klasse -> Eine Klasse der obersten Ebene kann nicht geschützt werden.

Instanzvariable -> Nur im selben Paket oder Unterpaket verfügbar. Kann nur außerhalb des Pakets abgerufen werden, während die Klasse erweitert wird.

Öffentlichkeit:

Klasse -> Zugriff über Paket / Unterpaket / ein anderes Paket

Instanzvariable -> Zugriff über Paket / Unterpaket / ein anderes Paket

Hier ist eine ausführliche Antwort

https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md

Mudassar
quelle
1
  • Öffentlichkeit

    Wenn ein Klassenmitglied mit public deklariert ist, kann von überall darauf zugegriffen werden

  • geschützt

    Wenn ein Klassenmitglied mit einem Schlüsselwort geschützt deklariert ist, kann von denselben Klassenmitgliedern, außerhalb von Klassenmitgliedern innerhalb desselben Pakets und geerbten Klassenmitgliedern auf es zugegriffen werden. Wenn ein Klassenmitglied geschützt ist, kann NICHT von einer externen Paketklasse darauf zugegriffen werden, es sei denn, die externe Paketklasse wird vererbt, dh die andere Paket-Superklasse wird erweitert. Ein geschütztes Klassenmitglied steht jedoch immer denselben Paketklassen zur Verfügung, unabhängig davon, ob dieselbe Paketklasse geerbt wird oder NICHT

  • Standard

    In Java ist die Standardeinstellung KEIN Schlüsselwort für den Zugriffsmodifikator. Wenn ein Klassenmitglied ohne ein Schlüsselwort für den Zugriffsmodifikator deklariert ist, wird es in diesem Fall als Standardmitglied betrachtet. Das Standardklassenmitglied steht immer denselben Paketklassenmitgliedern zur Verfügung. Mitglieder einer externen Paketklasse können jedoch NICHT auf Standardklassenmitglieder zugreifen, selbst wenn externe Klassen im Gegensatz zu geschützten Mitgliedern Unterklassen sind

  • Privat

    Wenn ein Klassenmitglied mit einem Schlüsselwort geschützt deklariert ist, steht es in diesem Fall NUR denselben Klassenmitgliedern zur Verfügung

alexvipul
quelle
-1

Zugriffsspezifizierer in Java: In Java gibt es 4 Zugriffsspezifizierer, nämlich privat, paketprivat (Standard), geschützt und öffentlich in aufsteigender Zugriffsreihenfolge.

Privat : Wenn Sie eine Klasse entwickeln und möchten, dass Mitglieder dieser Klasse nicht außerhalb dieser Klasse verfügbar gemacht werden, sollten Sie sie als privat deklarieren. Auf private Mitglieder kann nur in einer Klasse zugegriffen werden, in der sie definiert sind, dh in einer einschließenden Klasse. Auf private Mitglieder kann über diese Referenz und auch über andere Klasseninstanzen zugegriffen werden, die diese Mitglieder einschließen, jedoch nur innerhalb der Definition dieser Klasse.

Paket-privat (Standard) : Dieser Zugriffsspezifizierer bietet zusätzlich zu dem unten beschriebenen Zugriff den vom privaten Zugriffsspezifizierer angegebenen Zugriff.

Wenn Sie ein Paket und damit eine Klasse (z. B. Klasse 1) darin entwickeln, können Sie den Standardzugriffsspezifizierer (muss nicht explizit erwähnt werden) verwenden, um Mitglieder innerhalb der Klasse anderen Klassen in Ihrem (gleichen) Paket zugänglich zu machen. In diesen anderen Klassen (innerhalb desselben Pakets) können Sie auf diese Standardmitglieder in der Instanz von Class1 zugreifen. Sie können auch auf diese Standardelemente in Unterklassen der Klasse 1 zugreifen, z. B. Klasse 2 (in dieser Referenz oder in der Instanz der Klasse 1 oder in der Instanz der Klasse 2).

Grundsätzlich können Sie innerhalb desselben Pakets direkt auf Standardmitglieder für eine Instanz der Klasse oder auf 'diese' Referenz in Unterklassen zugreifen.

protected : Dieser Zugriffsspezifizierer bietet zusätzlich zu dem unten beschriebenen Zugriff den vom paketprivaten Zugriffsspezifizierer angegebenen Zugriff.

Wenn Sie ein Paket und damit eine Klasse (z. B. Klasse 1) darin entwickeln, sollten Sie den geschützten Zugriffsspezifizierer für Datenelemente in Klasse 1 verwenden, wenn Sie nicht möchten, dass auf dieses Mitglied außerhalb Ihres Pakets zugegriffen wird (z. B. im Paket des Verbrauchers von Ihr Paket (dh Client, der Ihre APIs verwendet) im Allgemeinen, aber Sie möchten eine Ausnahme machen und den Zugriff auf dieses Mitglied nur zulassen, wenn der Client eine Klasse schreibt, z. B. Class2, die Class1 erweitert. Im Allgemeinen sind geschützte Mitglieder unter "dieser" Referenz in abgeleiteten Klassen, dh Klasse 2, und auch in expliziten Instanzen von Klasse 2 zugänglich.

Bitte beachten Sie:

  1. Sie können nicht auf geerbtes geschütztes Mitglied von Klasse1 in Klasse2 zugreifen, wenn Sie versuchen, auf eine explizite Instanz von Klasse1 zuzugreifen, obwohl es darin vererbt ist.
  2. Wenn Sie eine andere Klasse Class3 in dasselbe / ein anderes Paket schreiben, das Class2 erweitert, kann auf geschützte Mitglieder aus Class1 in dieser Referenz und auch in einer expliziten Instanz von Class3 zugegriffen werden. Dies gilt für jede Hierarchie, die erweitert ist, dh auf geschützte Mitglieder kann in dieser Referenz oder Instanz der erweiterten Klasse weiterhin zugegriffen werden. Beachten Sie, dass Sie in Klasse 3, wenn Sie eine Instanz von Klasse 2 erstellen, nicht auf geschützte Mitglieder von Klasse 1 zugreifen können, obwohl diese vererbt wurden.

Unter dem Strich kann auf geschützte Mitglieder in anderen Paketen nur zugegriffen werden, wenn eine Klasse aus diesem anderen Paket die Klasse um dieses geschützte Mitglied erweitert und auf geschützte Mitglieder über 'diese' Referenz oder explizite Instanzen der erweiterten Klasse innerhalb der Definition von erweitert zugegriffen wird Klasse.

public : Dieser Zugriffsspezifizierer bietet zusätzlich zu dem unten beschriebenen Zugriff den vom geschützten Zugriffsspezifizierer angegebenen Zugriff.

Wenn Sie ein Paket und damit eine Klasse (z. B. Klasse1) darin entwickeln, sollten Sie den öffentlichen Zugriffsspezifizierer für Datenelemente in Klasse 1 verwenden, wenn auf dieses Mitglied in anderen Paketen zugegriffen werden soll, wenn eine Klasse 1 in einer anderen Klasse erstellt wurde Paket. Grundsätzlich sollte dieser Zugriffsspezifizierer verwendet werden, wenn Sie beabsichtigen, Ihr Datenelement ohne Bedingung einer Welt auszusetzen.

Tushar Baviskar
quelle