通过继承隐藏字段
在下面的代码示例中:
class Parent {
int x =5;
public Integer aMethod(){
System.out.print("Parent.aMthod ");
return x;
}
}
class Child extends Parent {
int x =6;
public Integer aMethod(){
System.out.print("Child.aMthod ");
return x;
}
}
class ZiggyTest2{
public static void main(String[] args){
Parent p = new Child();
Child c = new Child();
System.out.println(p.x + " " + c.x);
System.out.println(p.aMethod() + " \n");
System.out.println(c.aMethod() + " \n");
}
}
输出:
5 6
Child.aMthod 6
Child.aMthod 6
为什么当 px 打印 6 时 p.aMethod()
不打印 6?
谢谢
编辑
哎呀,有一个轻微的错字:问题应该是“为什么 p.aMethod() 在 px 打印 5 时不打印 5” - 谢谢@thinksteep
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
操作总是在对象上。在
p.aMethod()
和c.aMethod()
两种情况下,对象都是子对象,这就是为什么在这两种情况下都打印 6 的原因。当您直接访问变量时,它会读取与左侧关联的变量。Operations are always on Objects. In both cases,
p.aMethod()
andc.aMethod()
, object is child that is why it printed 6 in both cases. When you directly access variable directly it reads variable associated with left side.因为声明变量不会继承。类中有两份 x 副本,一份在父命名空间中,一份在子命名空间中。
Because declaring a variable doesn't inherit. You have two copies of x in the class, one in parent namespace, one in child namespace.
当您访问
px
等类成员字段(实例变量)时,不会进行多态解析。换句话说,您将从编译时已知的类中获得结果,而不是运行时已知的结果。对于方法调用来说这是不同的。它们在运行时被分派到引用所指向的实际类的对象,即使引用本身具有超类型。 (在虚拟机中,这是通过
invokevirtual
操作码发生的,请参见 http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc6.html#invokevirtual)。There's no polymorphic resolution being done when you access class member fields (instance variables) like
p.x
. In other words, you'll get the results from the class that's known at compile time, not what is known at run time.For method calls this is different. They are dispatched at run time to an object of the actual class the reference points to, even if the reference itself has a super type. (in the VM this happens via the
invokevirtual
opcode, see e.g. http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc6.html#invokevirtual).