Assume we have two packages p1
and p2
and classes p1.M1
extended by p2.M12
as follows:
package p1;
public class M1 {
void method1() {
System.out.println("Method 1 called");
}
}
package p2;
import p1.M1;
public class M12 extends M1 {
void method2() {
System.out.println("Method 2 called");
}
}
Let's extend M12
with p2.B
:
package p2;
public class B extends M12 {
public void doSomething() {
method1();
method2();
}
}
This gives a compilation error as method1
, being package-protected within p1
is not visible in p2
. method2
is visible without problems.
Now let's extend p2.M12
with p1.A
:
package p1;
import p2.M12;
public class A extends M12 {
public void doSomething() {
method1();
method2();
}
}
Here I'm getting a compilation error for both method2()
(which is understandable) and method1()
:
My question is: why is the method1
which is package-protected in the package p1
is not visible in the class A
from the same package p1
?
Visibility must flow through the class hierarchy.
The class hierarchy is
A --> M12 --> M1
The since
M1.method1
is not visible toM12
, it's not visible to any subclasses of it either, likeA
.I think the easiest way to understand this behavior is the idea of "A is a M12"
When you declared the inheritance, you told A to get its behavior from M12, but M12 has no visible method called method1.
Let's do an experiment for fun:
Forget A.. when you declare such method, it is allowed - if you do not have an @Override on it. however, if M1 was:
you could have:
now, back to the original code for M1 and M2 with the method re-declared and method one made public:
Then, you would be able to have
ok, this is a trivial case, but would be missing to complete the sequense... bottom line, semantically, you could explain by the IS relationship.
If more is needed (https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html):
The following table shows the access to members permitted by each modifier.
Access Levels
First, what is a member of a class? The Java Language Specification states
And what are they composed of? The JLS states
It also mentions
All of this is reworded in the chapter on Inheritance
The members of class
M1
aremethod1
(and all the methods ofObject
).M12
, being in a different package than its direct superclass,M1
, does not inheritmethod1
. The members ofM12
are therefore onlymethod2
.The direct superclass of
B
isM12
and is in the same package. It therefore inherits its member,method2
.B
knows nothing aboutmethod1
. If you had compiled your code withjavac
, you would have received acannot find symbol
compilation error instead. (It seems Eclipse is trying to guess what you were trying to do.)Similarly, the direct superclass of
A
isM12
, but is in a different package. It does not inheritmethod2
for that reason.A
doesn't know anything aboutmethod1
ormethod2
because it didn't inherit them. Both of those are symbols that cannot be found.