在子类中调用父方法将返回空值

时间:2019-02-16 17:11:38

标签: java inheritance

我试图通过使用父方法但从子类中显示父类的变量值。

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());
    }
}

我期望它输出hi,但是输出是null。我尝试过的事情:

  1. 在子类中使用getName()代替super.getName()
  2. 在子类中使用Parent p2 = new Parent();,然后使用p2.getName()
  3. 在父类中使用protected String name;

这些似乎都不起作用;最后,它们都仍然输出null。帮助吗?

5 个答案:

答案 0 :(得分:6)

您要在父对象中创建子对象,并设置 current 父对象的名称字段,但 不是 “孩子的父母”,这意味着您将创建多个“父对象”-一个对象的名称字段已设置,另一个(孩子的父母)名称字段从未设置过,但已经过测试。

作为附带的一点,Parent类不应做这种事情。应该是孩子“不可知论”。

答案 1 :(得分:4)

当您编写:“ child c1 = new child()”时,您正在创建一个全新的实例。这个新实例的null字段的值为name:child的构造函数不存在,因此您将获得默认的构造函数(该函数将调用父类的构造函数,而别无其他)。您的父类也没有构造函数,因此它也不执行任何操作,这会使您的name字段保留为默认值null

然后在此实例上调用input方法。因为此实例的实际类型是child,所以将运行input()类中定义的child方法,该方法将打印name字段的值,即{{1 }}。

是的,存在另一个实例(类型为null),该实例的parent字段设置为“ Hi”,但是您没有在该实例上调用name方法。您正在调用在input行中创建的实例的input方法。

答案 2 :(得分:3)

这种情况是在您进行Child并从父类Child c1 = new Child();继承了name属性的情况下创建的Parent新对象时发生的,该父类的继承属性{{ 1}}未设置,并且为namenull中的p1是一个完全不同的实例,其值未与main实例共享。

  

在子类中使用getName()代替super.getName()。

这两个都将导致c1,因为null是从父类name继承而来的,并且未初始化。在Parent方法中初始化的Parent对象是一个完全不同的实例,在main方法中的child实例未引用其属性。

  

使用父级p2 = new Parent();然后是子项中的p2.getName()   课。

同样,您正在创建input的单独实例,并且由于尚未初始化Parent实例name的{​​{1}}值,因此将返回null。

  

使用受保护的字符串名称;在父类中。

p2只是一个访问修饰符,它不会帮助您初始化从p2.getName()类继承的protected属性。

在视觉上是这样的: enter image description here

答案 3 :(得分:2)

在我留下的评论之后,因为注释中的代码格式非常有限。因此,这里的主要问题是孩子并不需要只拥有 a 父母。小孩需要确切想要的对象作为父母。通常是通过构造函数来完成的。所以我会让子类看起来像这样:

class Child extends Parent {
    private Parent parent;

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

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

然后,在您的父班中,您将拥有:

public void input() {
    String q = "hi";
    setName(q);
    Child c1 = new Child(this);
    c1.input();
}

答案 4 :(得分:0)

请给您另一个小样本以供使用:

public class main { 
    public static void main(String[] args) { 
        Parent p1 = new Parent(); 
        p1.input();
        Child c1 = (Child)P1; //this is a type cast, which is possible due to what is known as polymorphism
        c1.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); 
    } 
} 

class Child extends Parent { 
    public void input() { 
        System.out.print(super.getName()); 
    } 
}

在这个很小的示例(基于您自己的示例)中,您仅创建了一个parent实例。然后,将其作为子元素输入强制转换到c1变量中。因此,当您致电input ()时。它使用Child类而不是父类的实现。

它还假定您希望从实际类的外部使用多态性(例如,在本例中为main函数)。