2011-05-26 113 views
8

爲什麼下面的代碼打印「1」?java covariant返回類型

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); 
} 
} 

回答

13

因爲您指的是不受多態性影響的字段。如果您改用getX(),它會返回2

你問的是,在類中定義的字段x的價值A(因爲Base.getObject()回報A)。儘管CovariantReturn覆蓋了返回B的方法,但並不是指您的對象爲CovariantReturn

爲了擴大字段不受多態性影響 - 字段訪問是在編譯時實現的,所以無論編譯器看到什麼,都訪問了它。在你的情況下,該方法定義爲返回A,因此訪問A.x。另一方面,基於運行時類型調用方法。因此,即使您定義返回A但返回B的實例,您調用的方法將在B上調用。

+0

但我回到新B() – kris979 2011-05-26 10:41:37

+0

但該方法定義返回'A'。所以'A.x'就是被訪問的。 – Bozho 2011-05-26 10:44:09

+1

@kris您正在調用使用'A'的引用方法,因爲它有一個類型爲'A'的 – 2011-05-26 10:48:00

0

@ kris979雖然你要返回B,但我認爲返回類型是A的原因是什麼。因此,打印A中的x的值,即1。

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); 
    } 
} 

這段代碼打印 - 子和1

+0

不錯。簡單而整潔的答案 – STEEL 2018-02-07 04:56:02