gpt4 book ai didi

Java "trick", 重新定义子类成员

转载 作者:太空狗 更新时间:2023-10-29 22:52:49 25 4
gpt4 key购买 nike

我正在为 Java 考试进行培训,我在去年的科目中遇到了一些我不理解的东西。这是代码

class Mother {
int var = 2;

int getVar() {
return var;
}
}

class Daughter extends Mother {
int var = 1;

int getVar() {
return var;
}

public static void main(String[] args) {
Mother m = new Mother();
System.out.println(m.var);
System.out.println(m.getVar());
m = new Daughter();
System.out.println(m.var);
System.out.println(m.getVar());
}
}

问题是“这个程序的输出是什么?”。我会选择 2 2 1 1,但是在编译和运行这段代码时,我得到 2 2 2 1。

谁能告诉我为什么?

感谢阅读!

最佳答案

方法调用 m.getVar() 是一个虚拟方法调用。第二次调用它时,它会动态分派(dispatch)到派生的 Daughter.getVar(),它会执行您期望的操作(访问 Daugther.var 并返回它)。

成员字段没有这样的虚拟调度机制。所以 m.var 总是引用 Mother.var,即该变量的基类版本。

Daughter 类可以看作有两个不同的var 成员:一个来自Mother 和它自己的。它自己的成员“隐藏”了 Mother 中的成员,但可以使用 super.varDaughter 类中访问。

这方面的官方规范在 8.3 Field Declarations 部分的 JLS .引用:

If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class. The field declaration also shadows (§6.3.1) declarations of any accessible fields in enclosing classes or interfaces, and any local variables, formal method parameters, and exception handler parameters with the same name in any enclosing blocks.

请注意,它会变得非常有趣(添加了重点):

If a field declaration hides the declaration of another field, the two fields need not have the same type.

和:

There might be several paths by which the same field declaration might be inherited from an interface. In such a situation, the field is considered to be inherited only once, and it may be referred to by its simple name without ambiguity.

所以该段非常值得一读:-)

关于Java "trick", 重新定义子类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6008472/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com