-1

The code is like this :

class Base {
    int x = 10;

    public Base() {
        this.printMessage();
        x = 20;
    }

    public void printMessage() {
        System.out.println("Base.x = " + x);
    }
}

class Sub extends Base {
    int x = 30;

    public Sub() {
        this.printMessage();
        x = 40;
    }

    public void printMessage() {
        System.out.println("Sub.x = " + x);
    }
}

public class DispatchTest {
    public static void main(String[] args) {
        Base b = new Sub();
        System.out.println(b.x);
    }
}

The result is :

Sub.x = 0
Sub.x = 30
20

Can anybody please tell me how this code run? Why doesn't the costructor of class Base run?

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
huashui
  • 1,758
  • 2
  • 16
  • 24

4 Answers4

2

Because you created a new Sub object instance. The class Sub has the printMessage() method overriden, which means that the Base.printMethod() is not being executed.

The constructor of the Base class runs, but the this.printMessage() executes the printMessage method from the Sub class.

Immediatelly after the Sub's constructor has been invoked, the Base constructor is being called. It prints Sub.x = 0 because no x (in Sub) has been set so far. After that the value x gets assigned.

After the Base constructor is done, the rest of the Sub constructor is being executed. It prints calls the Sub's printMessage method again, but this time the value x has a value, and it prints Sub.x = 30.

The 20 comes from the System.out.println(b.x);.

You might wonder, why the value xis not assigned during the first printMessage call? Because you have x in your Sub class as well, so the x from the Base class is not visible!

Manuel
  • 3,828
  • 6
  • 33
  • 48
1

Your SuperClass constructor is always called but "Polymorphic behaviour cannot be seen when accessing overridden member variables".

  Base b = new Sub();
  System.out.println(b.x);

Now if you access x(which is present in both subclass and superclass) it is actually the type of reference variable which determines the value.

Note: This behaviour is different with overridden methods,in this case it is actually the type of object which determines the method to be called not the type of reference variable.

Algorithmist
  • 6,657
  • 7
  • 35
  • 49
1

The constructor

    public Sub() {
        this.printMessage();
        x = 40;
    }

is equivalent to

public Sub() {
        super();
        this.printMessage();
        x = 40;
}

So when you create

Base b = new Sub();

Base's constructor gets executed followed by Sub's constructor. See JLS 8.8.7, which states

The first statement of a constructor body may be an explicit invocation of another constructor of the same class or of the direct superclass


Base's constructor is calling printMessage() which is overriden by Sub. When it gets called from Base's constructor printMessage() prints x of Sub which is not yet initialized. This is an anti pattern, so Sub.x = 0 gets printed (x is not yet initialized, and hence default value of int which is 0 )


Now once the Base's constructor finishes, Sub's constructor gets called and now the x is initialized to 30 why?

because

class Sub extends Base {
    int x = 30;

    public Sub() {
        this.printMessage();
        x = 40;
    }
    ....

essentially means

class Sub extends Base {
    int x;

    public Sub() {
        {
            x=30;
        }
        this.printMessage();
        x = 40;
    }
    ....

hence this time printMessage() prints Sub.x = 30


finally 20 is printed because fields are NOT overriden.

sanbhat
  • 17,522
  • 6
  • 48
  • 64
0

When ever we are creating child class object then the following sequence of events will be executed automatically.

Step 1.Identification of instance members from parent to child and initialize them to default value.

after first step

Base instance variable is int x=0;
Sub instance variable is int x=0;

Step 2. Execution of instance variable assignments and instance blocks only in parent class

after second step

Base class instance variable is int x= 10;
Sub class instance variable is int x = 0;

Step 3.Execution of parent class constructor.

after third step

here you have a "printMessage()" invocation.It is overridden in child class Sub So Sub class method is executes and prints Sub class's variable x value,which is now assigned as 0 only.
So the out put now "Sub.x = 0". and Base class int x = 20; Sub class int x = 0;

Step 4.Execution of instance variables and instance blocks in child class.

After 4th step

Base class int x=20; Sub class int x=30;

Step 5.Execution of child constructor.

After 5th step.

In Sub class constructor you have "printMessage()" method invocation.So it will executes and prints output.
So the out put now "Sub.x = 30".
After the method invocation you have an assignment.
So now Base class int x=20; Sub class int x=40;

For now your Sub class constructor created successfully.
Now you a print statement of variable x on type reference "Base".So now "Base" class variable x will be prints as output.

So the out put is "20".

Prabhaker A
  • 8,317
  • 1
  • 18
  • 24