为什么“错误的”实例变量会被修改?

时间:2013-04-16 03:55:30

标签: java inheritance

我很困惑,因为我认为这是指当前调用该方法的对象 那么为什么在调用继承方法时,我的对象中的实例变量x没有被更改? 超类:

public class SuperBoss 
{
  int x = 50;

  public void changeX()
  {
   this.x  = 20;
  }
}

子类:

public class Boss extends SuperBoss
{
 int x = 10;
 public static void main(String[] args)
 {
  Boss b = new Boss();
  b.changeX();
  System.out.println(b.x); //prints 10
 }
}

为什么打印10而不是20?

2 个答案:

答案 0 :(得分:5)

简短回答:因为字段访问在Java中不是虚拟的。


SuperBoss声明x。

当Boss声明x时,x不会成为“虚拟”字段 - 它将成为一个隐藏在超类字段中的新字段。

当你在Boss上调用changeX时,这是SuperBoss中的一个方法,SuperBoss不知道Boss.x并且访问x不是虚拟的,所以它只是访问SuperBoss.x。

如果需要访问x是虚拟的,则需要提供getX方法,并覆盖Boss中的getX方法。现在,当SuperBoss的方法调用getX时,它会被重新路由到Boss中的getX。

答案 1 :(得分:1)

当您在子类中声明int x = 10时,当他们查看子类时,您将隐藏每个的超类变量。

当超类调用this.x时,它不会查看子类,所以允许它获取它自己的变量版本。

变量实际上并不是由它们在运行时的代码名称存储,因此重新定义它们不起作用 - SuperBoss#x将解析为符号表中的一个符号,而Boss#x将解析为另一个,所以如果你知道怎么弄它们,它们仍然存在。