Java子类重写move方法后调用,toString输出不符合预期问题咨询
问题原因
你的代码触发了Java的**属性隐藏(Field Hiding)**机制,具体逻辑如下:
- 你在
dog子类中重复定义了和父类organism完全同名的int x、int y属性,此时每个dog实例会同时存在两套独立的x/y变量:一套是从父类继承的父类属性,一套是子类自己新增的子类属性。 toString()方法定义在父类organism中,方法内部访问的this.x、this.y默认指向父类声明的x/y属性,不会读取子类的同名属性。- 你重写的
dog.move()方法属于子类自身的方法,内部访问的this.x、this.y默认指向子类自己新增的x/y属性。也就是说你调用Bobby.move(0, 1)时,修改的是子类的x/y,父类的x/y始终没有被改动,还是初始化时super(0,3)设置的0和3。 - 最后调用
toString()输出时读取的是未被修改的父类x/y,所以结果还是x: 0;y: 3,不符合你的预期。
修复方案
最简单的修复方式是直接删除dog类中重复定义的两行属性声明:
int x; int y;
子类不需要重复声明父类已经存在的非私有属性,删除后子类会直接继承父类的x/y,move()方法修改和toString()方法读取的就是同一套变量,输出结果就会符合预期。
如果因为特殊需求必须在子类保留同名x/y属性,你可以在move()方法中显式指定修改父类属性:
@Override public void move(int dx, int dy) { super.x = dx; super.y = dy; }
不过这种属于冗余设计,没有特殊需求不推荐使用。
内容的提问来源于stack exchange,提问作者Ethan Chan
相关产品推荐
相关产品推荐

