I've got some doubts regarding protected identifier. In the first chapter of Sun Certified Java Programmer Study Guide by K.Sierra I found the following information:
"Once the subclass-outside-the-package inherits the protected member, that member (as inherited by the subclass) becomes private to any code outside the subclass, with the exception of subclasses of the subclass."
I provided sample code which reflects the above statement and it is absolutely clear to me.
// Parent class
package package1;
import package2.Child;
public class Parent {
protected int i = 5;
}
// Child class
package package2;
import package1.Parent;
public class Child extends Parent {
// variable 'i' inherited
}
package package2;
public class Neighbour {
public void protectedTesting(){
Child child = new Child();
System.out.println(child.i); // no access
}
}
I've started experimenting and made a small change - moved Neighbour to package1. And there is an access to "i" variable which is a little bit surprising for me as it is not in accordance to statement "becomes private to any code outside the subclass"
Neighbour class after change:
package package1;
import package2.Child;
public class Neighbour {
public void protectedTesting(){
Child child = new Child();
System.out.println(child.i); // access!
}
}
Please clarify it to me. Thanks.
In short, protected
is package-private as well as visible to subclasses. Even the JLS is vague on this (JLS §6.6.2):
A
protected
member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.
It specifies that outside the package, only subclasses can access protected members. This implies that you can also access the variable within the package. It's poor wording, but true nonetheless that protected members have package-level visibility as well as subclass-level visibility.
See also:
- This related question
- The Java Trail for access control
And there is an access to "i" variable which is a little bit surprising for me as it is not in accordance to statement "becomes private to any code outside the subclass"
--> But you moved class Neighbour
in package package1
which is true according to "Protected members can be accessed by classes in same package"
"Once the subclass-outside-the-package inherits the protected member, that member (as inherited by the subclass) becomes private to any code outside the subclass, with the exception of subclasses of the subclass."
--> Inside package it is still protected and not private for all classes within the package.
The truth is not in "Sun Certified Java Programmer Study Guide" but in the Java Language Specification
6.6.2. Details on protected Access
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.
protected
visibility includes package level visibility.
Inheritance allows you to treat your Child
object as an instance of Parent
.
As the member i
of Parent
is declared in the same package, it is accessible from Neighbour
.
package package1;
import package2.Child;
public class Neighbour {
public void protectedTesting() {
Parent neighboured = new Child();
System.out.println(neighboured.i); // access
}
}
来源:https://stackoverflow.com/questions/12861807/protected-member-behavior-once-it-was-inherited