MGorgon
MGorgon

Reputation: 2597

Why is a private method invoked in super context?

With this code:

public abstract class A {
    private String runNow() {
        return "High";
    }

    public abstract String cos();

    static class B extends A {
        public String runNow() {
            return "Low";
        }

        public String cos() {
            return "cos from B";
        }
    }

    public static void main(String args[]) {
        A[] a = new B[] {new B(), new C()};
        for (A aa : a) {
            System.out.println(aa.runNow() + " " + aa.cos());
        }
    }
}

class C extends A.B {
    public String runNow() {
        return "Out";
    }

    public String cos() {
        return "cos from C";
    }
}

Why is the runNow method from class A invoked and not from the subclasses?

Upvotes: 4

Views: 134

Answers (5)

RealSkeptic
RealSkeptic

Reputation: 34618

As you were already told, the problem is that runNow() is private. It is therefore not overridden, and accessing it through a reference of type A would get you to the A class's definition, whereas trying to access it through a B reference would get the subclasses.

I would like to point out, though, that this "odd" behavior is only possible because the method that is doing all this (your main method) is defined inside A. If your main method was in another class that has access to these classes, you'd get an error that indicates that the method is not reachable at all. If you think about that, it may be more clear to you why the methods runNow() in B and C do not override the one in A. From the point of view of any object outside of A, there is no runNow() method at all - it's an implementation detail and not part of the contract of A. Therefore, it cannot be overridden, and the runNow() in B and C are just new methods that you don't have access to when you use B and C polymorphically as A.

Upvotes: 1

Chetan Kinger
Chetan Kinger

Reputation: 15212

Why is the runNow method from class A invoked and not from the subclasses

private methods are not inherited in subclasses. Therefore, they cannot be overriden. Since runtime-polymorphism only applies to overriden methods, the runNow method from A will always be called. Change the runNow method in A to a public method and you will get the desired output since public methods are inherited and can be overriden.

Upvotes: 1

Zano
Zano

Reputation: 99

It's because method runNow() in class A is private, so in classes B and C you're not overriding it. And when you're calling method aa.runNow() it's called directly from class A.

Try to do some experiment and change your method in class A to this:

private String runNow2() {
    return "High";
}

public String runNow() {
    return "High";
}

Also change your System.out to this one:

System.out.println(aa.runNow() + " " + aa.cos() + " " + aa.runNow2());

Now the result will be as expected.

Hope it helps!

Upvotes: 1

Lalit Mehra
Lalit Mehra

Reputation: 1273

It is because runNow() is a private method in class A. Private methods are not inherited so could not be overridden.

private String runNow(){
      return "High";
 }

And also that you have created a reference of type A

A[] a=new B[]{new B(),new C()};

so the only runNow() which will be called to complete the call is of class A as the compiler does not know about runNow() methods in class B and C

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726529

Short answer is "because runNow() is private".

When you compile this call aa.runNow() the compiler sees that class A has runNow method which is private, and that your code is calling this private method. Since private methods cannot be overriden, the compiler routs the call to A's runNow() method - the only one it knows to exist in this context.

The fact that B and C also introduce their methods by the same name does not matter to the compiler, because these methods are new in the subclasses. The compiler cannot consider them overrides without breaking encapsulation of class A, which designated runNow a private method.

Upvotes: 2

Related Questions