10

在以下代码示例中:

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

为什么p.aMethod()px打印6时不打印6?

谢谢

编辑

哎呀,有点错字:问题应该是“为什么 p.aMethod() 在 px 打印 5 时不打印 5” - 谢谢@thinksteep

4

3 回答 3

12

当您访问类成员字段(实例变量)时,不会进行多态解析,例如p.x. 换句话说,您将获得编译时已知的类的结果,而不是运行时已知的结果。

对于方法调用,这是不同的。它们在运行时被分派到引用指向的实际类的对象,即使引用本身具有超类型。(在 VM 中,这通过invokevirtual操作码发生,参见例如http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc6.html#invokevirtual)。

于 2011-12-27T17:25:12.650 回答
1

操作总是在对象上。在这两种情况下,p.aMethod()对象c.aMethod()都是子对象,这就是为什么在这两种情况下都打印 6 的原因。当您直接访问变量时,它会读取与左侧关联的变量。

于 2011-12-27T17:26:42.980 回答
0

因为声明变量不会继承。您在类中有两个 x 副本,一个在父命名空间中,一个在子命名空间中。

于 2011-12-27T17:13:03.867 回答