为什么从父类打印字段,从子类打印方法(Java)

时间:2018-01-31 11:43:18

标签: java inheritance polymorphism

我有这样的父类和子类:

class Parent {

    public String value = "Parent";

    public String getValue() {

        return value;
    }
}

class Child extends Parent {

    public String value = "Child";

    public String getValue() {
        return value;
    }

}

public class Test {

    public static void main(String[] args) {

    Parent abc = new Child();       

    System.out.println(abc.value +"  | "+abc.getValue());


    }
}

如果我运行代码,结果为Parent | Child。为什么这样?为什么现场'价值'来自Parent类,方法来自Child,而不是来自Child?

3 个答案:

答案 0 :(得分:1)

您重写getValue()方法的原因。你不能覆盖字段。

引用abc的类型在编译时很重要,在运行时期间,实际值abc指向的对象类型决定了将调用哪个方法。由于abc是对Child类实例的引用,因此将调用最适合Child对象的方法。

答案 1 :(得分:1)

在Java中,无法覆盖字段。该字段绑定到对象的Reference类型,在这种情况下它是Parent。因此,您将看到父类变量的值。

但是,可以覆盖方法,并且在getValue()方法的代码中也会反映出来。因此,您将看到在运行时绑定的实际对象的方法输出,即Child类。

答案 2 :(得分:1)

Java语言的设计没有覆盖字段的功能,但允许您覆盖方法 - 这是您无法使用字段获得多态效果的主要原因。当您在子类中使用覆盖方法(具有完全相同的签名和返回类型)时,会考虑多态性。由于字段不支持多态,因此采用声明类的字段:

Parent abc = new Child(); // declared type is Parent 

您可能需要查看此链接(https://docs.oracle.com/javase/tutorial/java/IandI/override.html)以了解有关覆盖方法的更多信息:

子类中的实例方法具有相同的签名(名称,加上其参数的数量和类型),返回类型作为超类中的实例方法覆盖超类的方法。 子类覆盖方法的能力允许类从行为“足够接近”的超类继承,然后根据需要修改行为。覆盖方法具有相同的名称,参数的数量和类型,以及返回类型作为它覆盖的方法。重写方法还可以返回由重写方法返回的类型的子类型。此子类型称为协变返回类型。

关于何时考虑多态性的其他信息,您可以在这里找到:

https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html