2017-04-01 62 views
3

我有一個超類名爲TestSuper如何從子類中獲取數據字段而不是超類?

public class TestSuper { 
    int a = 0; 
} 

,我有2名爲TestSub子類和TestSub2,在我的主類擴展TestSuper

public class TestSub extends TestSuper{ 
    int a=1; 
} 

public class TestSub2 extends TestSuper{ 
    int a=2; 
} 

我創建了一個發生在一個類型TestSuper的方法並返回它的一個值,並在主屏幕上顯示它

public class Main { 
public static void main(String[] args){ 

    System.out.println(test(new TestSub())+" "+test(new TestSub2())); 
} 
public static int test(TestSuper b){ 
    return b.a; 
} 
} 

但輸出是「0 0」而不是「1 2」,我該怎麼辦?

+2

您只能覆蓋子類中的方法。你不能覆蓋字段。 –

+0

只需在你的子類'TestSub(){a = 1;}' – Maraboc

回答

3

您需要將參考轉換爲說出您想要的參考。

public static int test(TestSuper b){ 
    return b instanceof TestSub ? ((TestSub) b).a : 
      b instanceof TestSub2 ? ((TestSub2) b).a : 
      b.a; 
} 

如果這似乎是不必要的複雜,那是。你應該使用多態。

public class TestSuper { 
    int a = 0; 
    public int getA() { return a; } 
} 

public class TestSub extends TestSuper { 
    int a = 1; 
    public int getA() { return a; } 
} 

public class TestSub2 extends TestSuper { 
    int a = 2; 
    public int getA() { return a; } 
} 

public static int test(TestSuper b) { 
    return b.getA(); 
} 
+0

添加一個構造,所以如果你重新定義了子類中的字段並將子類的實例轉換爲超類,那麼返回值就是超類的值,但是如果你通過方法或getter來請求值,那麼返回值就是subClass的值!不知道,現在我想知道爲什麼? – Cherif

+0

@Charif非靜態方法遵循繼承,字段不遵守。 –

+1

現在我想像和包含兩個字段具有相同名稱但不同值的子類的實例。是發生了什麼 – Cherif

0

你可以看看背後的理論,然後做唯一合理的事情 - 忘記編寫這樣的代碼。

在良好的面向對象中,你認爲你的領域是你的「祕密」內部實現的一部分。您不要在超類上下文中使用子類的字段。期。

對於在超類中創建一個保護字段並在子類中使用它,你甚至非常保守。

0

當你調用測試方法是這樣的:

test(new TestSub())+" "+test(new TestSub2()) 

您使用上溯造型。上傳分離接口和對象的實現。但是,爲了分離接口和實現並在多態中實現真正的實現,您必須使用多態結構。實例變量不是多態的。正因爲如此,實際上你會調用TestSuper類中的一個變量。

只有實例方法是多態的。