javaclassconstructorupcasting

Creating class fields in the constructor


I recently started learning Java. I got to the point of upcasts and downcasts and this is what I encountered. I understand how type conversion works, but this moment keeps me awake. If you create class fields outside the constructor and assign values to them, then during the upcast, as per the rules, you cannot get the field of the child class, but if these fields are created directly in the constructor, then during the upcast I can safely refer to the fields of the child class.

Parent class:

public class Parent {
    String name = "Parent name";
    int age = 30;

    Parent() {

    }

    public void hello(){
        System.out.println("Parent say hello");
    }
}

Child class with creation in constructor:

public class Child extends Parent {

    public Child() {
        this.name = "Child name";
        this.age = 10;
    }

    public void hello() {
        System.out.println("CHild say hello");
    }
}

Child class with creation out constructor:

public class Child extends Parent {
    public String name;
    public int age;

    public Child() {
        this.name = "Child name";
        this.age = 10;
    }

    public void hello() {
        System.out.println("CHild say hello");
    }
}

Main code testing first case:

public class Main {

    public static void main(String[] args) {
        Parent p = new Child();
        System.out.println(p.name);
    }
}

Output: Child name

Main code testing second case:
(The Main code is the same.)
Output: Parent name

I looked at a ton of video tutorials and documentation sites, but no one considered my case.


Solution

  • In the first test case, class Parent is instantiated and the string Parent name is assigned to member variable name in class Parent. Then the Child class is instantiated and its constructor assigns a new value to member name in class Parent, namely Child name. Now in method main, of class Main, p.name will return the current value of variable name in class Parent which is Child name.

    In the second test case, you are creating another name variable in class Child. This is a different variable to name in class Parent. Hence when you assign a value to name in the constructor of class Child, you are assigning it to the variable in class Child and not to the variable in class Parent. Hence name in class Parent is still Parent name. So, in method main, of class Main, p.name refers to name in class Parent (even though you assign p to an instance of class Child) and therefore the second test case prints Parent name.

    Parent p = new Child();
    

    Here p is a Parent and not a Child and therefore has no access to member variables in class Child. This is known as variable hiding. There are many questions (and answers) regarding variable hiding. Just enter the following in the search box at the top of this Web page:

    [java] variable hiding