I have a problem understanding protected members inheritance and visibility.
I know it is visible in the same package and subclasses.
But in the following code it is not visible in a subclass.
A.java
package a;
public class A {
public static void main(String[] args) {
}
protected void run() {
}
}
B.java
package b;
import a.A;
public class B extends A {
public static void main(String[] args) {
B b = new B();
b.run(); // this works fine
}
}
C.java
package b;
import a.A;
public class C extends A{ // it will not work also if extends B
public static void main(String[] args) {
B b = new B();
b.run(); // this is the problem; not visible
}
}
Why b.run() in the last class is invisible?
This is because class C
can see A
's protected methods from within its own inheritance tree. But it's not allowed to access A
's protected methods for another class (B
) from a different inheritance tree. C
is not part of B
's inheritance tree (by this, I mean that's it's not a parent of B
), therefore the behavior is normal.
EDIT: Added documentation reference as requested
6.6.2.1. Access to a protected Member:
If the access is by a field access expression
E.Id
, or a method invocation expressionE.Id(...)
, or a method reference expressionE :: Id
, whereE
is a Primary expression (§15.8
), then the access is permitted if and only if the type ofE
isS
or a subclass ofS
.
Applying the above to this case, because the variable b
is not an instance of C
or a subclass of C
, access to the protected method b.run()
is not allowed.
Also addressing Codebender
's comment about the packages. Note that, if the C
class would have been defined in the same package as the A
class, where the protected run()
method is defined, then the above rule wouldn't apply, and you would be able to access the method as shown in your code.