Viele Bücher, die die Java-Sprache einführen (einschließlich "Thinking in Java"), geben eine relativ einfache Einführung in protected, im Grunde nur einen Satz:Durch protected modifizierte Member sind innerhalb des aktuellen Pakets und für seine Unterklassen sichtbar. Diese Aussage ist zu vage und führt oft zu Missverständnissen. Tatsächlich besteht die protected-Sichtbarkeit aus zwei Punkten:

  • protected-Member einer Basisklasse sind innerhalb des Pakets und für Unterklassen sichtbar;
  • Wenn die Unterklasse und die Basisklasse nicht im selben Paket liegen, kann in der Unterklasse eine Instanz der Unterklasse auf die von der Basisklasse geerbten protected-Methoden zugreifen, aber nicht auf die protected-Methoden einer Instanz der Basisklasse.

Wir können das protected-Schlüsselwort durch die folgenden Beispiele zur Sichtbarkeit von protected-Methoden weiter vertiefen. Wenn Sie auf einen Aufruf stoßen, an dem ein protected-Member beteiligt ist, bestimmen Sie zuerst, woher das protected-Member stammt und welchen Sichtbarkeitsbereich es hat; dann können Sie beurteilen, ob die aktuelle Verwendung zulässig ist. Betrachten Sie die folgenden sieben Beispiele:

Beispiel 1

package p1; public class Father1 { protected void f() {} //Die protected-Methode der Elternklasse Father1 } package p1; public class Son1 extends Father1 {} package p11; public class Son11 extends Father1{} package p1; public class Test1 { public static void main(String[] args) { Son1 son1 = new Son1(); son1.f(); // Kompilierung OK ----(1) son1.clone(); // Kompilierungsfehler ----(2) Son11 son = new Son11(); son11.f(); // Kompilierung OK ----(3) son11.clone(); // Kompilierungsfehler ----(4) } }

Betrachten Sie für das obige Beispiel zunächst (1) und (3). Die Methode f() wird von der Klasse Father1 geerbt, und ihre Sichtbarkeit umfasst das Paket p1 und dessen Unterklassen Son1 und Son11. Da das Paket der Klasse Test1, die die Methode f() aufruft, ebenfalls p1 ist, ist die Kompilierung bei (1) und (3) erfolgreich. Betrachten Sie als Nächstes (2) und (4). Die Sichtbarkeit der Methode clone() umfasst das java.lang-Paket und alle seine Unterklassen. Für die Anweisungen "son1.clone();" und "son11.clone();" sind die clone()-Methoden in den Klassen Son1 und Son11 sichtbar, aber für Test1 nicht sichtbar, daher schlägt die Kompilierung bei (2) und (4) fehl.

Beispiel 2

package p2; class MyObject2 { protected Object clone() throws CloneNotSupportedException{ return super.clone(); } } package p22; public class Test2 extends MyObject2 { public static void main(String args[]) { MyObject2 obj = new MyObject2(); obj.clone(); // Kompilierungsfehler ----(1) Test2 tobj = new Test2(); tobj.clone(); // Kompilierung OK ----(2) } }

Für (1) stammt die clone()-Methode aus der Klasse MyObject2 selbst, daher umfasst ihre Sichtbarkeit das Paket p2 und Unterklassen von MyObject2. Obwohl Test2 eine Unterklasse von MyObject2 ist, können Sie in Test2 nicht auf die protected clone()-Methode der Basisklasse MyObject2 zugreifen, daher schlägt die Kompilierung fehl. Für (2), da in Test2 auf die von der Basisklasse MyObject2 geerbte clone()-Methode über ihre eigene Instanz zugegriffen wird, ist die Kompilierung erfolgreich.

Beispiel 3

package p3; class MyObject3 extends Test3 { } package p33; public class Test3 { public static void main(String args[]) { MyObject3 obj = new MyObject3(); obj.clone(); // Kompilierung OK ------(1) } }

Für (1) stammt die clone()-Methode aus der Klasse Test3, daher ist ihre Sichtbarkeit package p33 und ihre Unterklasse MyObject3. Und (1) wird genau in der Klasse Test3 des Pakets p33 aufgerufen, das zum selben Paket gehört, daher ist die Kompilierung erfolgreich.

Beispiel 4

package p4; class MyObject4 extends Test4 { protected Object clone() throws CloneNotSupportedException { return super.clone(); } } package p44; public class Test4 { public static void main(String args[]) { MyObject4 obj = new MyObject4(); obj.clone(); // Kompilierungsfehler -----(1) } }

Zu (1): Die clone()-Methode stammt aus der Klasse MyObject4, daher ist ihre Sichtbarkeit auf das Paket p4 und dessen Unterklassen beschränkt (hier gibt es keine Unterklassen). Aber die Klasse Test4 befindet sich im Paket p44, daher ist die Sichtbarkeit nicht gegeben und die Kompilierung schlägt fehl.

Beispiel 5

package p5; class MyObject5 { protected Object clone() throws CloneNotSupportedException{ return super.clone(); } } public class Test5 { public static void main(String[] args) throws CloneNotSupportedException { MyObject5 obj = new MyObject5(); obj.clone(); // Kompilierung OK ----(1) } }

Zu (1): Die clone()-Methode stammt aus der Klasse MyObject5, daher ist ihre Sichtbarkeit auf das Paket p5 und dessen Unterklassen beschränkt (hier gibt es keine Unterklassen). Die Klasse Test5 befindet sich ebenfalls im Paket p5, daher ist die Sichtbarkeit gegeben und die Kompilierung ist erfolgreich.

Beispiel 6

package p6; class MyObject6 extends Test6{} public class Test6 { public static void main(String[] args) { MyObject6 obj = new MyObject6(); obj.clone(); // Kompilierung OK -------(1) } }

Für (1) stammt die clone()-Methode aus der Klasse Test6, daher ist ihre Sichtbarkeit package p6 und ihre Unterklasse MyObject6. Klasse Test6 ist ebenfalls im Paket p6, also ist die Sichtbarkeit erfüllt und die Kompilierung läuft durch.

Beispiel 7

package p7; class MyObject7 extends Test7 { public static void main(String[] args) { Test7 test = new Test7(); test.clone(); // Kompilierungsfehler ----- (1) } } public class Test7 { }

Für (1) stammt die clone()-Methode aus der Klasse Object, daher ist die Sichtbarkeit dieser clone()-Methode package java.lang und ihre Unterklasse Test7. Da die Klasse MyObject7 nicht in diesem Bereich liegt, ist die Sichtbarkeit nicht erfüllt und die Kompilierung schlägt fehl.

Quelle: http://blog.csdn.net/justloveyou_/article/details/61672133