为什么我不继承超类变量?

Why am I not inheriting the superclass variable?

我正在输出

SubClass subClass = new SubClass(4);
System.out.println(subClass.getVal());

有了这两个类:

public class SuperClass {
    public int x = 99;

    public int superClassMethod() {
        return -1;
    }
}


public class SubClass extends SuperClass {
    public int x;

    public SubClass(int value) {
        x = value;
    }

    public int getVal() {
        return x;
    }
}

这会按预期输出 4。但是假设我在 SubClass 构造函数中注释掉了 x = value 行。为什么它输出 0(我假设未启动变量的默认值)而不是 99,继承自超类?

如果我将 return x 更改为 return superClassMethod();,它似乎可以正确地从超类中提取 -1。那么为什么是方法而不是变量呢?

您正在继承,但您在女儿 class 中明确重新声明 x 会覆盖您女儿 class 范围中的 x

SubClass中省略public int x;,应该没问题。

public int x; 行表示新定义了名为 x 的变量。因此,您将在 class 中有两个名为 x 的变量 - 一个在 SuperClass 中,另一个在 SubClass 中。它们具有不同的位置,因此可以包含不同的值。由于您没有在 SubClass 内初始化,它的默认值为 0.

如果完全删除 SubClass 中的声明,从 SubClass 访问 x 将访问父 classes 中的变量 x .

当变量在不同范围内具有冲突的名称时,它始终使用最近范围内的变量,即使它尚未设置为任何内容。

为了区分其他范围内的变量,在变量前面加上thissuper:

public class SuperClass {
    protected int x;
}
public class SubClass extends SuperClass {
    private int x;
    public SubClass(int x) {
        x = 2; // sets the parameter variable
        this.x = 2; // sets the instance variable
        super.x = 2; // sets the super class' instance variable
    }
}

问题是您的 Subclass 也有一个同名 x 的 int。然后它将打印该默认值,而不是您的超级 class.

尝试删除那个 int,它应该可以工作!

这都是因为这段代码。

public SubClass(int value) { //what ever You pass you will get the result.
        x = value;
    }

这里x是一个实例变量所以,在继承中只允许Methodsoverride永远不会是Instance Variable所以,x会初始化要么由 0 如果 new SubClass() 使用。 或者,xvalue 如果 new SubClass(int value) 使用。

您正在呼叫

SubClass subClass = new SubClass(4);  //initialize your local x with 4
System.out.println(subClass.getVal());    // Result you will get is 4

因为x里面的SubClass就是shadowing variable。那就是它隐藏了 SuperClass 变量 x。所以你无法从 SuperClass 中获取值。当您评论 x = value; 时,它会为 class 的 int 成员返回默认值,即 0.

你在子类和超类中都有一个成员,在对象子类的实例中,可见的 x 是你在子类中定义的那个,如果你需要 superclass x 你需要使用super关键字。

因此在该范围内唯一有效的 x 是 子类

中的实例之一
public class SubClass extends SuperClass {
    public int x;   // this line hides the x defined in the super class.
    ...

    public int getVal() {
        return x;
    }
}

因为SubClass中的x隐藏了SuperClass中定义的x,并且因为没有指定作用域

return x;

javac 将其翻译为

return this.x;