Reputation: 1302
This is an example in A Programmer’s Guide to Java™ SCJP Certification A Comprehensive Primer - Third Edition - Khalid A. Mughal Rolf W. Rasmussen which I can't understand.
I know that we can't access a protected member if we didn't inherit it into a sub-class defined in another package.
But I still can't understand why we can't access it from the sub-class of the sub-class.
The example follows
package packageA;
public class A {
protected int z;
}
package packageB;
import packageA.A;
public class B extends A {
void action(A obj1, B obj2, C obj3) {
z = 10; // z in B - Works
obj1.z = 10; // Won't work for obvious reason
obj2.z = 10; // z in B - Works
obj3.z = 10; // z in C - Works
}
}
class C extends B {
void action(A obj1, B obj2) {
z = 10; // Works
obj1.z = 10; // Won't work for obvious reason
obj2.z = 10; // z in B - WHY DOESN'T THIS WORK?????
}
}
Upvotes: 3
Views: 1195
Reputation: 23976
The currently-accepted answer doesn't answer the question. It explains why you can't access the member z
of an instance of A
from within the body of B
or C
. But the question asks why you can't access the member z
of an instance of B
from within C
.
The reason is that B
is not a subclass of C
. Read the Java specification, section 6.6.2.1:
Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.
In addition, if Id denotes an instance field or instance method, then:
If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2.1
(bolding mine)
So within B
you can say obj3.z
because obj3
is of type C
, and C
is a subclass of B
.
But within C
you cannot say obj2.z
, because obj2
is of type B
and B
is not a subclass of C
.
To summarize the meaning of protected:
Suppose a protected member is declared within the body of class A
.
(1) You can access the protected member from anywhere in the package containing A
.
(2) Additionally, a subclass S
of A
, defined in a different package, can access the protected member on instances of S
or instances of classes that inherit from S
, but not on instances of classes that S
inherits from.
That last clause is the key point when it comes to answering this question.
Upvotes: 3
Reputation: 7327
Protected members can only be accessed by subclasses of the class where it's declared or classes in the same package as the class where the protected member is declared. Classes B and C in your case are declared in different packages to that of Class A. That's why you can't access 'z' via a reference to class A. If you moved classes B and C into the same package as A, it will work.
This is why you can't access obj2.z in class C, as 'z' is declared in a class in a different package.
Upvotes: 1