Reputation: 4275
Let's take the following code:
public class Test {
class A {
public A() {}
private void testMethod() {
System.out.println("A");
}
}
class B extends A {
public B() { super(); }
private void testMethod() {
System.out.println("B");
}
}
public Test() { }
public A get() {
return new B();
}
public static void main(String[] args) {
new Test().get().testMethod();
}
}
I would expect that code to write B
. A
is written instead.
It may feel weird (at least to me) the fact that a class can call private methods of the inner classes that it contains (why did they make it that way?), but what i really can't understand is why polymorphism doesn't work.
I mean, if from Test.main()
we can call A.testMethod()
it's obvious we call also call B.testMethod()
. Java can also determine the dynamic type of an object so, why does Java call the method of the declared type instead the one of the dynamic type? This behavior can be checked:
public static void main(String[] args) {
B b = new Test().new B();
A a = b;
b.testMethod(); // writes B
a.testMethod(); // writes A
}
Also, why does this happen only when Test.A.testMethod()
is private
?
Upvotes: 1
Views: 142
Reputation: 328568
It is defined in the JLS #15.2.3
if the compile-time declaration has the private modifier, then the invocation mode is nonvirtual
And JLS #15.4.4
If the invocation mode is nonvirtual, overriding is not allowed. Method m of class T is the one to be invoked.
Where T
is the declared type, in your case A
, as opposed to the actual type of the object at runtime (B
in your case). In other words, there is no polymorphism with private methods.
Upvotes: 3
Reputation: 887215
The behavior you're expecting comes from virtual methods.
Private methods are never virtual.
Instead, you have two unrelated methods which happen to have the same name.
Upvotes: 5
Reputation: 44181
In Java, all non-static methods are by default "virtual functions". Two particular kinds of non-static methods are non-virtual: those marked with the keyword final, which cannot be overridden, and private methods, which are not inherited.
http://en.wikipedia.org/wiki/Virtual_function#Java
Upvotes: 0