The output of this simple program is This is base.
public class mainApp{
private void func(){
System.out.println("This is base");
}
public static void main(String[] args){
mainApp newObj = new derived();
newObj.func();
}
}
class derived extends mainApp{
public void func(){
System.out.println("This is derived");
}
}
-
My question is when we are using this line
mainApp newObj = new derived();are we not actually creating an object of derived class using a reference of base class mainApp. So, when I am using the object to call it’s method why don’t I get the method from the derived class? Why I get the method from the base class. -
using this line,
mainApp newObj = new derived();, are we working with a reference of mainApp OR we are working with an object of derived class. Which one is correct?
The reason that you’re getting the base class method is that the base class version of
funcis declaredprivate, and Java does not allow private methods to be overridden by subclasses. This means that if you extend a base class and by pure coincidence decide to name a private member function the same name as a private member function in the base class, you don’t accidentally change the behavior of the base class’s member functions. You are indeed working with an object of typederived, but because the reference is statically typed as amainApp, callingfuncis interpreted as calling the private methodfuncinmainApprather than the public methodfuncinderived. Changing the code to readfixes this, because the static type of
dis nowderivedand the call tofunchas a different meaning.At the JVM bytecode level, the instruction used to call private member functions is
invokespecialwhereas the instruction used to call normal, override-able member functions isinvokevirtual. The two have totally different semantics;invokespecialbegins looking in the current class (or some base class for things like constructors), whereasinvokevirtuallooks in the class corresponding to the object’s type at runtime.