web-dev-qa-db-de.com

Warum kann eine Klasse nicht als geschützt definiert werden?

Ich weiß, das ist eine dumme Frage, aber ich habe immer noch Zweifel, die geklärt werden müssen. 

Meine Frage ist warum können wir eine Klasse nicht als protected definieren? 

Ich weiß, dass wir es nicht können, aber warum? Es sollte einen bestimmten Grund geben.

61
M.J.

Weil es keinen Sinn macht.

Ein geschütztes Klassenmitglied (Methode oder Variable) ist genauso wie package-private (Standardsichtbarkeit), es kann jedoch auch von Unterklassen aus darauf zugegriffen werden.
Da es in Java kein Konzept wie 'subpackage' oder 'package-Vererbung' gibt, wäre das Deklarieren von class protected oder package-private dasselbe.

Sie können verschachtelte und innere Klassen jedoch als geschützt oder privat deklarieren.

78
Nikita Rybak

Wie Sie wissen, ist der Standardwert für den Zugriff auf Paketebene und geschützt für die Paketebene plus Nichtpaketklassen, was jedoch die Klasse erweitert (zu beachten ist, dass Sie die Klasse nur dann erweitern können, wenn sie sichtbar ist!). Sagen wir es so: 

  • geschützte Top-Level-Klasse wäre für Klassen in ihrem Paket sichtbar. 
  • jetzt außerhalb des Pakets (Unterklassen) sichtbar zu machen, ist etwas verwirrend und knifflig. Welche Klassen dürfen unsere geschützte Klasse erben? 
  • Wenn für alle Klassen eine Unterklasse zulässig ist, ähnelt sie dem öffentlichen Zugriffsbezeichner. 
  • Wenn keine, dann ist es dem Standard ähnlich. 

Da es nicht möglich ist, diese Klasse auf nur wenige Klassen zu beschränken (die Klasse kann von allen verfügbaren Klassen in einem Paket/außerhalb eines Pakets nur von wenigen Klassen geerbt werden), werden keine geschützten Zugriffsbezeichner verwendet für Top-Level-Klassen. Daher ist es nicht erlaubt.

30
Akash5288
public class A
{
    protected class B
    {
    }
}
13
irreputable

Durch das Festlegen eines geschützten Felds ist das Feld sowohl innerhalb des Pakets als auch außerhalb des Pakets nur durch Vererbung (nur innerhalb der Kindklasse) verfügbar.

Wenn wir also eine Klasse geschützt machen dürfen, können wir sehr einfach innerhalb des Pakets darauf zugreifen. Wenn Sie jedoch außerhalb des Pakets auf diese Klasse zugreifen möchten, müssen Sie zunächst die Entität erweitern, in der diese Klasse definiert ist.

Und da ein Paket nicht erweitert werden kann (importiert werden kann), wird es durch die Definition einer geschützten Klasse erneut als Paket-privat festgelegt. Dies ist vergleichbar mit der Festlegung als Standard, was wir bereits tun können Klasse Privat wird es nur mehrdeutig machen.

Weitere Informationen finden Sie unter Warum eine äußere Java-Klasse nicht privat oder geschützt sein kann

3
Naresh Joshi

@Nikita Rybak Antwort hat gute Punkte, aber mangelnde Details, ich kann die Idee nicht ohne tiefes Nachdenken selbst verstehen. Das Folgende ist, was ich dachte, und jetzt sollte ich den Grund vollkommen verstehen.

Bei vier Zugriffsmodifizierern wird davon ausgegangen, dass die erste Ebene öffentlich ist und die vierte Ebene privat ist (basierend auf dieser Tabelle in Folge). Das erste, was wir wissen sollten, ist, warum die Klasse in der obersten Ebene nicht als privat definiert werden kann.

Wenn also "private Klasse foo" (Ein privates Mitglied definiert, d. H. Klasse selbst ist ein Mitglied) erlaubt ist, was ist das äußere (welches das Mitglied enthält)? Dateibereich? Nein, File Outer ist sinnlos, da sogar mehrere Klassen in einer Datei in separate Klassendateien kompiliert werden. Also das Äußere ist Paket. Der 3. Level-Zugriffsmodifizierer default bedeutet jedoch bereits "package-private". Daher wird der private Zugriffsmodifikator der 4. Ebene nicht verwendet/erlaubt. 

Verschachtelte private Klasse ist jedoch zulässig, da die direkte äußere Klasse Klasse ist, nicht Paket, z. :

class PrivateNestedMain {
    private static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

Was ist nun, wenn "protected class foo" dies zulässt? protected main Merkmal ist eine Unterklasse, daher sollte das äußere (Paket) SOLLTE (aufgrund des Up-to-Geltungsbereichs, ist aber optional) Stil der Unterklasse, dh Unterpaket oder package A extends package B, aber wir wissen nicht so etwas. Protected kann also nicht das volle Potenzial (Hauptbereich ist Unterklassenweit) in der obersten Ebene, das das äußere Paket ist (dh keine solche Unterpaket-Sache), ausnutzen, aber geschütztes Potential kann das volle Potenzial in verschachtelten Klassen nutzen, das die äußere ist Klasse (dh kann Unterklasse sein):

class ProtectedNestedMain {
    protected static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

Beachten Sie, dass das oben erwähnte "kann das volle Potenzial nicht ausnutzen", da es die Unterklasse nicht erreichen kann, nur weil keine äußere Unterklasse, das heißt, tatsächlich geschützt werden kann, es ist nur eine Frage der Wahl Vermeiden Sie, den Job von package-private zu duplizieren, wenn äußere nicht subklassenfähig ist, siehe unten.

Meine Verwirrung wird hauptsächlich durch die berühmte Tabelle unter https://docs.Oracle.com/javase/tutorial/Java/javaOO/accesscontrol.html verursacht:

 enter image description here

Wenn 1. Ebene (öffentlich) und 3. Ebene (Paket-privat) zulässig ist, wie in aller Welt ist die dazwischen liegende 2. Ebene (geschützt) nicht zulässig?

Öffentliche Unterstützungsunterklasse, so leicht zu irreführen. Der korrekte Weg zum Lesen dieser Tabelle ist 

Öffentliche Unterstützungsunterklasse, wenn die äußere Unterklasse eine Funktion hat.

Dieselbe Irreführung trifft auf package-private zu, paket-private unterstützt keine Unterklasse (N in cell) bedeutet nicht, dass das Unterklassenkonzept auf äußere angewendet wird.

Das heißt, wir sollten die Spalte Subclass ignorieren, wenn das Subclass-Feature nicht in outer verfügbar ist:

 enter image description here

Wie wir jetzt sehen können, sind sowohl protected als auch package-private jetzt auf der gleichen Ebene (Y-Y-N), keine Verwirrung mehr darüber, warum Zwischenstufen nicht zulässig sind. Insgesamt wird Java nur über -Paket-Private ausgewählt, um Verwirrung zu vermeiden (ist nur eine Frage der Wahl, aber das geschützte Hauptmerkmal ist eine Unterklasse, daher ist Package-Private überlegen) und das Ergebnis , nur zwei Zugriffsmodifizierer in der obersten Ebene zulässig:

Auf oberster Ebene - public oder package-private (kein expliziter Modifikator).

2
林果皞

Geschützt ist nicht öffentlich. Protected hat sowohl Zugriff auf Paketebene als auch Zugriff außerhalb von Paketen nur durch Vererbung. Wenn eine Klasse sagt, dass A außerhalb eines Pakets eine Klasse aus einem anderen Paket (mit einer durch INHERITANCE geschützten Methode) enthält, kann sie auf die Methoden dieser Klasse B zugreifen hat geschützte Methoden, aber die von dieser Klasse abgeleiteten Unterklassen, dh A kann nicht auf die geschützten Methoden zugreifen. Das Gegenteil geschieht mit public.

Beispiel:

package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}
1
Shruthi reddy

verhalten von "protected" = Verhalten von "default" + "verwende es in jeder Unterklasse in einem Paket".

Jedenfalls haben wir einen Standard-Zugriffsmodifizierer für Klassen, der einzige Vorteil, den wir mit einem geschützten Zugriffsmodifikator erhalten können, ist: - durch Verwendung in jedem Paket durch Unterklassen. Für die Unterklasse wäre die Sichtbarkeit der übergeordneten geschützten Klasse jedoch privat. Es kann also nicht darauf zugegriffen werden. Wenn Sie über eine geschützte Top-Level-Klasse verfügen, kann grundsätzlich keine äußere Klasse durch Unterklasse darauf zugreifen. So für eine Top-Level-Klasse geschützt ist sinnlos.

0
madhu

protected bedeutet, dass auf jede Klasse im selben Paket und auf Unterklassen auf das Mitglied zugegriffen werden kann, auch wenn sie sich in einem anderen Paket befinden.

Beispiel:

package a;
class parent{
 protected void p();
}
package b;
import a.p;
class child extends parent{
  //you can access method which is protected in the parent in the child 
}
class another extends child {
 //here you can not access the protected method 
}
0
Yogesh Patil

Für diese Frage ist es sinnvoll, dass JVM in C (Sun JVM) und C++ (Oracle JVM) geschrieben ist. Während der Kompilierung werden .class-Dateien aus unserer Java-Datei erstellt und eine Klasse mit dem Schlüsselwort Protected deklariert dann wird von JVM nicht darauf zugegriffen. 

Die Antwort darauf, warum auf die geschützte Klasse nicht von JVM zugegriffen werden kann, ist die, dass geschützte Felder innerhalb desselben Pakets oder auf andere Pakete nur durch Vererbung zugänglich sind und JVM nicht so geschrieben wird, dass sie die Klasse erben wird. Ich hoffe, diese Frage ist zufriedenstellend :) 

Ebenso kann eine Top-Level-Klasse nicht privat sein. Erklärung wie folgt:

Was passiert also, wenn wir eine Klasse als privat definieren, ist diese Klasse nur innerhalb der Entität zugänglich, in der sie definiert ist, was in unserem Fall das Paket ist.

Wenn Sie also einen privaten Zugriff auf die Klasse definieren, wird der Zugriff auf die Klasse innerhalb desselben Pakets möglich, mit dem das Standardschlüsselwort bereits für uns geeignet ist. Daher ist es nicht vorteilhaft, eine Klasse als privat zu definieren, da nur die Dinge mehrdeutig werden.

0
Anurag Prasad

Die Antwort von @ Akash5288 ergab für mich keinen Sinn:

Wenn für alle Klassen eine Unterklasse zulässig ist, ähnelt sie dem öffentlichen Zugriffsbezeichner.

Da es nicht möglich ist, diese Klasse auf nur wenige Klassen zu beschränken (die Klasse kann von allen verfügbaren Klassen in einem Paket/außerhalb eines Pakets nur von wenigen Klassen geerbt werden), werden keine geschützten Zugriffsbezeichner verwendet für Top-Level-Klassen. Daher ist es nicht erlaubt.

Sie können dann dieselbe Logik auf geschützte Methoden und Variablen anwenden, sie sind dann auch "public-ähnlich". Alle Klassen außerhalb eines Pakets können unsere öffentliche Klasse erweitern und ihre geschützten Methoden verwenden. Warum ist das Beschränken von Methoden und Variablen auf erweiterte Klassen in Ordnung, aber das Beschränken der gesamten Klasse nicht in Ordnung? "Ähnlich wie in der Öffentlichkeit" ist nicht "gleich wie in der Öffentlichkeit". Meine Interpretation ist, dass es vollkommen in Ordnung ist, eine geschützte Klasse zuzulassen, da es gut ist, geschützte Methoden zuzulassen.

Die Antwort "Sie können eine Klasse nicht erweitern, auf die Sie nicht zugreifen können/sehen" ist logischer.

0
k-s

Geschützt : SICHTBAR nur auf Paketebene *.

klasse ist definiert protected---> es kann nicht erweitert werden von außerhalb des Pakets (nicht sichtbar).

Wenn es nicht erweitert werden kann, ist es sinnlos, es als protected beizubehalten, da dann default Zugriff wird, der erlaubt ist.

Gleiches gilt für private definierte Klassen.

Hinweis: Geschachtelte oder innere Klassen können definiert werden protected oder private.

* : Explore protected - Schlüsselwort, für diese Antwort habe ich es kurz gefasst.

0
Narendra Singh