Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a parent method in a child class returns a null value

I'm trying to display the value of a variable from the parent class by using a parent method but from within a child class.

public class A {
    public static void main(String[] args) {
        Parent p1 = new Parent();
        p1.input();
    }
}
class Parent {
    private String name;
    public void setName(String newName) {
        name = newName;
    }
    public String getName() {
        return name;
    }
    public void input() {
        String q = "hi";
        setName(q);
        Child c1 = new Child();
        c1.input();
    }
}
class Child extends Parent {
    public void input() {
        System.out.print(super.getName());
    }
}

I was expecting it to output hi but instead the output is null. Things I've tried:

  1. Using getName() instead of super.getName() in the child class.
  2. Using Parent p2 = new Parent(); and then p2.getName() in the child class.
  3. Using protected String name; in the parent class.

None of these seem to work; all of them still output null in the end. Help?

like image 677
EeveeLover Avatar asked Feb 16 '19 17:02

EeveeLover


4 Answers

You're creating a Child object within a Parent object, and you're setting the current parent object's name field, but not the Parent of the Child, meaning you've more than one Parent object being created -- one whose name field is being set, and the other (the parent of the child) whose name field is never set, but is tested.

As a side bit, a Parent class should not be doing this sort of thing. It should be child "agnostic".

like image 74
Hovercraft Full Of Eels Avatar answered Sep 22 '22 19:09

Hovercraft Full Of Eels


When you write: "child c1 = new child()", you're making an entirely new instance. This new instance has value null for its name field: The constructor of child isn't there, therefore you get the default constructor (which calls the parent class constructor and nothing else). Your parent class also has no constructor, so it also does nothing, which leaves your name field at its default value of null.

You then call the input method on this instance. Because the actual type of this instance is child, the input() method defined in your child class runs, which prints the value of the name field, which is null.

Yes, there's ANOTHER instance (of type parent), which has a name field set to 'Hi', but you're not calling the input method on that instance. You're calling the input method of the instance you create in line child c1 = new child();.

like image 29
rzwitserloot Avatar answered Sep 24 '22 19:09

rzwitserloot


This happening as a new and separte Child object is created when you did Child c1 = new Child(); which inherits the name property from the parent class Parent, whose inherited property name is not set and is null. The p1 in the main is a totally different instance whose values are not shared with the c1 instance.

Using getName() instead of super.getName() in the child class.

Both of these will result in null as the name is inherited from the parent class Parent and it is not initialized. The Parent object you have initialized in the main method is a totally different instance and whose properties is not referred by the child instance in the input method.

Using Parent p2 = new Parent(); and then p2.getName() in the child class.

Again you are creating a separate instance of Parent and since you have not initialized the name value of the p2 instance p2.getName() will return null.

Using protected String name; in the parent class.

protected simply is an access modifier, it won't help you to initialize the name property inherited from the Parent class.

Here it is visually: enter image description here

like image 34
Fullstack Guy Avatar answered Sep 20 '22 19:09

Fullstack Guy


Following up on a comment I left, since code formatting is very limited in comments. So the main issue here is that the child doesn't just need to have a parent. The child needs to have the exact desired object as a parent. The way this is typically done is via a constructor. So I'd make the child class look like this:

class Child extends Parent {
    private Parent parent;

    public Child(Parent parent) {
        this.parent = parent;
    }

    public void input() {
        System.out.print(parent.getName());
    }
}

Then, in your parent class, you'd have:

public void input() {
    String q = "hi";
    setName(q);
    Child c1 = new Child(this);
    c1.input();
}
like image 30
Jordan Avatar answered Sep 24 '22 19:09

Jordan