1

Why B() when initializing part of class A using overrides method print() defined in class B?

Expected output:
A
4

Real output:
0
4

public class Test
{
    public static void main(String[] args)
    {
        new B();
    }
}

class A
{
    public A()
    {
        print();
    }
    
    public void print()
    {
        System.out.println("A");
    }
}

class B extends A
{
    int a = 4;
    public B()
    {
        print();
    }
    
    @Override
    public void print()
    {
        System.out.println(a);
    }
}
Den2
  • 21
  • 4

1 Answers1

0

You have overriden print in class B.

So if you call print on an instance of B it will always go there.

This also happens while a constructor is still running, which you seem to not have expected, and it can also cause problem because not all fields in B may have been initialized yet. For this reason, it is bad practice to call any method from a constructor that is not final.

Your example nicely demonstrates that:

You say you expected to output of "A" for that first print statement, most people would have expected the output of "4", but what really happens is you get a "0" because the field B.a is not yet initialized.


public A()
    {
        print();
    }

Here, print() is not a static method, so this is short for this.print(). And even though you are in the constructor of class A, this was being called as part of new B() from the constructor of B, so this is an instance of B (at a point of time when the constructor of B has not yet fully done its work).

Thilo
  • 257,207
  • 101
  • 511
  • 656