Lenny
Lenny

Reputation: 93

How parent and child fields initialized in Inheritance?

I am facing one confusion.

Here is my small code snippet

public class Father {

    public String x;

    public Father() {
        this.init();
        System.out.println(this);
        System.out.println(this.x);
    }

    protected void init() {
        x = "Father";
    }

    @Override
    public String toString() {
        return "I'm Father";
    }

    void ParentclassMethod(){

        System.out.println("Parent Class");
    }

}


public class Son extends Father {
    public String x;


    @Override
    protected void init() {
        System.out.println("Init Called");

        x = "Son";
    }

    @Override
    public String toString() {
        return "I'm Son";
    }

    @Override
    void ParentclassMethod(){
        super.ParentclassMethod();
        System.out.println("Child Class");
    }

}

public class MainCLass{

    public static void main(String[] args){

        Son ob = new Son();

}

So when I'm creating a Son's class instance which is inherited from Class Father, so JVM automatically calls Father's class constructor. It creates Son type instance when Father's constructor called otherwise Father's fields wont initialized. So far Good..!

As you can see field x is derived from Father's class into Son's class. And my code initializing x using init() method.

Then why its showing null.

Its very confusing. Can any one explain ?

Upvotes: 1

Views: 1375

Answers (1)

TiiJ7
TiiJ7

Reputation: 3412

Variables are not polymorphic in Java. Since you re-declared x inside Son, this variable will actually be a different x than the one in Father. So in the init method of Son, you are initializing the Son's x, but not the Father's x.

On the other hand, your statement System.out.println(this.x); is inside the Father class so it only knows about Father's x. Since you no longer initialize this variable due to overriding the init method, the x in Father remains null (the default) and thus it will print null.

You can fix the problem by removing public String x; from the Son class. This will make Father's x the only x, removing the problem.

However, in general, you want to make this variable private instead of public. You should also never call a non-final method in a constructor. It can only introduce bugs. The proper way to initialize it in this case would be to have a constructor with a parameter in Father:

public class Father {
    private String x;

    protected Father(String x) {
        this.x = x;
        System.out.println(this);
        System.out.println(this.x);
    }

    public Father() {
        this("Father");
    }

    // Rest of father's code, without the init method
}

public class Son extends Father {
    public Son() {
        super("Son");
    }

    // Rest of son's code, without the init method
}

Upvotes: 2

Related Questions