José D.
José D.

Reputation: 4275

Inherit in private methods of inner classes

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

Answers (3)

assylias
assylias

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

SLaks
SLaks

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

Dark Falcon
Dark Falcon

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

Related Questions