Java子类构造函数继承了成员

时间:2015-01-22 21:37:36

标签: java constructor subclass superclass

我有一个问题,为什么这段代码在执行时打印出值0.我不完全理解SubClass构造函数中发生了什么,为什么当我擦除被覆盖时方法implicitValue,它打印出10. SubClass构造函数是否使用SuperClass构造函数? 谢谢。

class SuperClass {
    protected int superClassValue;

    public SuperClass() {
        superClassValue = implicitValue();
    }

    public int implicitValue() {
        return 10;
    }

    public int getValue() {
        return superClassValue;
    }
}

class SubClass extends SuperClass {
    private int subClassValue;

    public SubClass() {
        subClassValue = 20;

    }

    public int implicitValue() {
        return subClassValue;

    }
}

class Example {
    public static void main(String argv[]) {
        SubClass ss = new SubClass();
        System.out.println("The value is " + ss.getValue());

    }
}

4 个答案:

答案 0 :(得分:3)

TL; DR

问题是来自implicitValue的{​​{1}}由超类隐式SuperClass构造函数(SubClass)通过super()方法使用,之后implicitValue()将在SubClass中执行构造函数,因此它返回subClassValue = 20;的默认值,subClassValue字段为int


  

SubClass构造函数是否使用SuperClass构造函数?

是的,start的子类构造函数总是调用超类构造函数,所以代码

0

相同
public SubClass() {
    subClassValue = 20;
}

但是让我们来看看你的代码。您正在打印超类中存在的public SubClass() { super();//superclass constructor subClassValue = 20; } 方法的结果

getVlaue()

如您所见,它会返回public int getValue() { return superClassValue; } 的值。在调用superClassValue之前,您正在创建getVlaue()实例,因此您正在调用代码

ss

表示你正在调用超类的构造函数,它看起来像

super();//superclass constructor
subClassValue = 20;

所以使用public SuperClass() { superClassValue = implicitValue(); } 方法的返回值初始化this.superClassValue,但由于dynamic binding(后期绑定),JVM将尝试从实际类{{}开始搜索此方法的实现{1}} implicitValue(),由于此类有自己的重写版本,因此将调用它

this

SubClass尚未设置为

public int implicitValue() {
    return subClassValue;
}

因此subClassValue仍有默认值super();// <-- we are still here subClassValue = 20;// this line was not executed yet ,这意味着

subClassValue

所以

0

将返回superClassValue = implicitValue(); //will be initialized with 0;

答案 1 :(得分:1)

是的,如果没有明确给出这样的调用,子类构造函数会隐式调用超类构造函数。但由于在0中覆盖了implicitValue方法,因此会打印SubClass

  1. 调用超类构造函数。这里,创建了对象的SuperClass部分。所有变量都已初始化。由于没有给出明确的值,编译器会为superClassValue提供默认值0。然后超类构造函数调用implicitValue(),它调用子类的方法。此方法返回superClassValue,其初始化为0。此值已明确分配回superClassValue
  2. 子类将其subClassValue初始化为10
  3. 调用getValue()方法,它返回superClassValue,即0The value is 0已打印。
  4. 如果您要删除implicitValue中的SubClass方法,则会继承该方法的SuperClass版本,该方法会返回10。< / p>

    如果您要修改implicitValue中的SubClass方法以返回5,那么它会将superClassValue初始化为5,并会打印{ {1}}。

答案 2 :(得分:1)

  1. 在您的情况下:默认情况下将调用SuperClass构造函数。

  2. 当Java进程:新的SubClass()时。它将首先调用SuperClass的构造函数。当调用SuperClass的构造函数时 - 从implicitValue()返回的值将被赋值给superClassValue - 被调用的方法implicitValue()是SubClass的方法(按照你的想法调用SupperClass的NOT implicitValue() - OOP的多态性特征) 。当调用SubClass的implicitValue()时,subClassValue尚未初始化(subClassValue = 20;尚未运行),因此subClassValue仍为ZERO。这就是你在输出中看到零的原因。

  3. 在SubClass中删除override implicitValue时。 hiddenValue()被调用是SupperClass的implicitValue - &gt;这就是你在输出中看到10的原因。

答案 3 :(得分:-1)

听起来你的Override方法或子类有问题。因为它听起来就像它实现了一个变量,值没有被实例化,所以它默认为0然后当你删除它时超类接管导致你获得值10。