我正在探索Java中的方法和变量继承,尤其是类的实例如何查找字段(静态变量)。
但是,我无法获得下面的Java片段中预期的行为。
更令人困惑的是,运行用Python编写的相同(?)东西可以获得预期的结果。
class Up {
public static int n = 1;
public int m;
public void setter() {
System.out.println("I looked up " + this.n);
this.m = this.n;
System.out.println(this.m);
}
}
class Sub extends Up {
public static int n = 6;
public int m = 5;
public Sub() {
super();
}
}
class Run {
public static void main(String[] args) {
Sub foo = new Sub();
foo.setter();
System.out.println(foo.m);
}
}
class Up:
n = 1
def setter(self):
print("I looked up", self.n)
self.m = self.n
print(self.m)
class Sub(Up):
n = 6
m = 5
foo = Sub()
foo.setter()
print(foo.m)
Python代码按预期运行并打印出来:
I looked up 6
6
6
但是,等效的Java代码已打印出来:
I looked up 1
1
5
我想我在这里有两个问题:
Java为什么将this.n解释为Up类中初始化的字段而不是foo的实际类Sub?
在成功查找1之后,Java应该将foo.m绑定到1。打印出this.m似乎表明它已经拥有,但是直接从main方法中打印出foo.m表明它已经拥有了。不是,为什么呢?
我怀疑这是由于Java“在运行时访问变量”(我仍在解决这个问题)引起的,我猜这可能解释了数字1,但我希望有人能解释一下对我来说2号后面发生了什么?
答案 0 :(得分:1)
对于第二个问题,您有两个名为“ m”的实例变量。在Class Up中声明的一个,在Sub类中声明的一个在Up中隐藏变量。因此,当您调用setter()(这是Up的方法)时,它将使用在Up中找到的m的值(Up不了解其任何子类中找到的变量)。
但是,当您以后打印foo.m时,由于foo是Sub的不变性,因此它将使用Sub中的m值(仍为5)。
删除Sub类中m的声明,看看会发生什么。