I'm a student, learning Java. I know, protected
means access from children
or the same package
. Here we inherit and override a protected method. And after such an action, whenever the base class wants to call its own method it calls the new overridden one from the subclass. I've been debugging this for a while and marked the execution order with comments. But I can't understand why doesn't it call the base method when I clearly call that from inside the base class constructor?
public class Solution {
public static void main(String[] args) {
new B(); // first
}
public static class A {
public A() {
initialize(); // third
}
protected void initialize() {
System.out.println("class A"); // we never go here
}
}
public static class B extends A {
public B() {
super(); // second
initialize(); // fifth
}
protected void initialize() {
System.out.println("class B"); // fourth, sixth
}
}
}
That's a task from one website, so basically the solution is to change access modifier of the initialize
method from protected
to private
. But I still fail to understand why is the problem happening.
As Dakoda answered, the root cause is polymorphism
. That means we may create child objects, but refer to them as their parent type and when we call the methods of the parent layer we actually refer to the child's methods.
In my case, I create a child object (marked //first) B
, which has its own body of the initialize
method. One nuance of the inheritance is that it doesn't include constructors, so I can call the parent's constructor (marked //second). Inside the parent's constructor, I call the initialize
method - that is the polymorphism because I call the method of the child from its parent abstraction layer.
Here is the answer to the question - this happens, because we only allocated memory for a B
instance, that means, we took A
as our base and started to extend it (while we can overwrite anything inside). The only two things we did are:
initialize
method code. The code for this method that is inside the base is now lost for this object.This concept of polymorphism
is designed that way and there is no way for us to access the base method unless we specifically create an object that is either A
itself or a child that doesn't overwrite this method.