8

为什么下面的代码打印“1”?

class A {
    int x = 1;
}

class B extends A {
    int x = 2;
}

class Base {

    A getObject() {
        System.out.println("Base");
        return new B();
    }
}

public class CovariantReturn extends Base {

B getObject() {
   System.out.println("CovariantReturn");
   return new B(); 
}
/**
 * @param args
 */
public static void main(String[] args) {
    Base test = new CovariantReturn();
    System.out.println(test.getObject() instanceof B);
    System.out.println(test.getObject().x);
}
}
4

3 回答 3

13

因为您指的是不受多态性影响的字段。如果您改为使用getX()它,它就会返回2

您要问的是,x类中定义的字段值A(因为Base.getObject()返回A)。即使CovariantReturn重写要返回的方法B,您也不会将对象称为CovariantReturn.

扩展一下字段如何不受多态性影响 - 字段访问是在编译时实现的,因此无论编译器看到什么,这就是访问的内容。在您的情况下,该方法定义为返回A,因此A.x可以访问。另一方面,方法是根据运行时类型调用的。因此,即使您定义返回A但返回 的实例B,您调用的方法也会在 上调用B

于 2011-05-26T10:39:28.927 回答
0

@ kris979 虽然您要返回 B,但我认为不同之处在于返回类型是 A。因此打印了 A 中 x 的值,即 1。

于 2011-05-26T10:47:11.480 回答
0

正如 Bozho 指出的那样 - 实例变量永远不会受到多态性的影响。让我给你一个简单的小例子。

class Base {
    int i = 1;
    void method() {
        System.out.println("in base");
    }
}

class Sub extends Base {
    int i = 2;

    void method() {
        System.out.println("in sub");
    }
}

public class Test { 
    public static void main(String[] args) {
        Base obj = new Sub();
        obj.method();
        System.out.println(obj.i);
    }
}

此代码将打印 -在 sub 和 1

于 2013-01-08T19:16:41.747 回答