-1
class Base {
    private void func(){ // method overridden if public
        System.out.println("In base func method");         
    };
    public void func2() {
        System.out.println("func2");
        func(); // alternatively, this could be: ((Derived) this).func();
    }
}

class Derived extends Base {
    public void func(){
        System.out.println("In Derived Class func method"); 
    }
}

class Test {
    public static void main(String [] args) {
        Derived d = new Derived();
        d.func2();
    }
}

As written, this code will call the func() of the Base class because this method is private and there is no method overriding going on.

However, if the func() line of func2() is changed to ((Derived) this).func(), the func() of the Derived class will be called. From what I can tell, it seems as if the Derived object is being treated like a Base object once the control enters the func2() of the Base class.

Is my understanding correct? How can my understanding be reconciled, if at all, with method overriding in the case where the func() of the Base class is instead public rather than private and runtime binding occurs? Does the call to func() in func2() first find the Base class func() and then decide to use func() in the subclass due to method overriding? Exactly what happens at runtime here?

Quantum Dot
  • 395
  • 1
  • 7
  • 12
  • http://idownvotedbecau.se/noresearch/ If you has searched StackOverflow for [`java private override`](https://stackoverflow.com/search?q=java+private+override) you'd have found lots of answers. – Andreas May 10 '18 at 23:13
  • I mean I did do research...I clearly understood a lot of what's going on here already. My goal here was to reconcile my understanding between questions I already looked at. It really does seem like whenever an object gets a method call in another class it is treated like if that method is acting on a variable of its own type; i.e., the Derived object is treated as if it had been casted like `Base obj = d;`. And then `func()` is resolved by the type Base but then runtime polymorphism takes over and `func()` in Derived is executed. I didn't come here with no understanding/research. – Quantum Dot May 10 '18 at 23:47
  • All the duplicates say the same thing: *You cannot **override** a private method*. So when the *compiler* sees a call to a private method, it generates a *direct* method call, which means that the call won't even look for override at runtime. This is unlike non-private method calls, when the compiler generates a *dynamic* method call, where the actual method called at runtime might be a subclass method (dynamic dispatch). – Andreas May 11 '18 at 09:29
  • At the low level (bytecode), calls to static methods are `invokestatic` instructions, calls to constructors and private instance methods are `invokespecial` instructions, and calls to non-private instance methods are `invokevirtual` instructions. – Andreas May 11 '18 at 09:35

1 Answers1

0

According to what I have understood from your question, you are confused about what happens during the runtime when the method func() is called from func2() of the Base class. When Java finds a method inside the superclass's method that is overridden in the subclass, it finds that the method is in the subclass. So, in your case, the method func() is executed, not of the Base class but of the Derived class due to late binding. Because the Derived Object is calling the method func2(), the method func() comes back to the subclass (Derived). If, however, the call were made to the Base class, the func of the Base class would be called.

So the overall takeaway is this: Late binding is purely based off of the object calling the function. Java checks for overridden methods of the subclass during the late binding (run-time).

Akash Veerappan
  • 76
  • 1
  • 1
  • 6