After adding the packages, the question is much more difficult. I've tried this, and I changed your main program to
public class C1 extends b.B1 implements I1 {
public static void main(String[] args) {
a.A1 a = new a.C1();
System.out.println(a.m1());
a.A1 b = new b.B1();
System.out.println(b.m1());
}
}
(I actually used different package names to avoid conflicts with the variable names. So my code looks a bit different from the above.)
I've confirmed that this prints "b" and "a". That is, if I create a new B1
, its m1
method does not override the one in A1
. Thus if I print b.m1()
, since b
is of type A1
, polymorphism doesn't kick in, and the method declared in A1
is called. So what's going on with C1
?
C1
inherits the m1
method from B1
. But even though the m1
method in B1
doesn't override the one in A1
, the m1
method in C1
, which it inherits from B1
, actually does override the one in A1
. I think it has to do with this clause in 8.4.8.1:
mA is declared with package access in the same package as C, and either C declares mC or mA is a member of the direct superclass of C.
Here C
is your C1
class. mC
is the m1
that's inherited from B1
. In this case, "C declares mC" is false, because C1
doesn't declare m1
, it inherits it. However, I believe "mA is a member of the direct superclass of C" is true. As I understand it, B1
has all the members that A1
has. B1
declares its own m1
, and since it's not overriding, it's a new m1
that causes the m1
it inherits from A1
to be hidden. But even though it's hidden, it's still a member. Thus the condition that mA
is a member of the direct superclass of C
(which is B1
) is satisfied, and thus all the conditions of 8.4.8.1 are satisfied and thus the inherited m1
in C1
overrides the one in A1
.