Search code examples
javaoverridingprotected

Why does calling a method from base class calls the child method?


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.


Solution

  • 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:

    1. We created a constructor (it wasn't included in the base, as mentioned above)
    2. We overwrote the 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.