2017-04-24 131 views
25

我無法理解以下輸出。Java繼承字段

我不知道爲什麼輸出是10,我覺得行A a = new B()創建B類的新實例,我想結果應該是20

class A { 
    int i = 10; 
} 

class B extends A { 
    int i = 20; 
} 

public class MainClass { 
    public static void main(String[] args) { 
     A a = new B(); 

     System.out.println(a.i); 
    } 
} 

爲什麼這個是這樣的..請說明。

+11

你不重寫值我在這裏,你的影子 –

+2

看看這篇文章。 http://stackoverflow.com/questions/685300/is-there-a-way-to-override-class-variables-in-java –

+0

多態性不適用於字段,它爲方法做的方式。你使用了一個'A'類型的變量來查找字段'i',所以你得到'A'類型的副本,而不是類型'B'中的副本。當你查看字段時,重要的是變量的類型,而不是對象的類。 –

回答

30

首先,看看Hiding Fields(強調)

在一類,具有相同的名稱作爲超一個字段的字段隱藏超類的領域,即使它們的類型不同

換句話說,這是不是「遺產」,因爲你實際上隱藏A小號0123的iB背後「,並且您正在使用A的引用對象,因此您正在獲取其字段。如果您確實B b = new B(),您會看到20,如預期。


如果您期望真正的覆蓋,請嘗試使用方法。

class A { 
    public int get() { 
     return 10; 
    } 
} 

class B extends A { 
    @Override 
    public int get() { 
     return 20; 
    } 
} 

A a = new B(); 
System.out.print(a.get()); // 20 

如果你真的想看到兩者兼而有之,看到這個例子。

class A { 
    int i = 10; 
} 

class B extends A { 
    int i = 20; 

    @Override 
    public String toString() { 
     return String.format("super: %d; this: %d", super.i, this.i); 
    } 
} 

而且

A a = new B(); 
System.out.print(a); // super: 10; this: 20 
1

成員變量i已在class A中定義。

爲了實現你在找什麼,改變class B如下圖所示:

class B extends A { 
    public B() { 
     i = 20; 
    } 
} 
20

在java中不能覆蓋實例變量。您正在獲得的輸出是預期的。在Java中,您只能覆蓋實例方法而不是實例變量。

如果您希望將20作爲輸出,您可以對這些實例變量使用getter方法。

class A { 
    int i = 10; 

    int getI() { 
     return i; 
    } 
} 

class B extends A { 
    int i = 20; 

    int getI() { 
     return i; 
    } 
} 

public class MainClass { 
    public static void main(String[] args) { 
     A a = new B(); 

     System.out.println(a.getI()); 
    } 
} 
10

多態性不適用於領域在Java.Evaluating變量作出決定在編譯時所以總是基類的變量被訪問。

4

因爲您定義了兩個變量:一個在子類B中,另一個在超類A中具有相同名稱。

A a = new B(); 
a.i; // refers to A.i 

如果你投的AB,它將訪問B.i

System.out.println(((B)a).i); 

我認爲你需要使用1個變量:

class A { 
    int i; 

    public A() { 
     i = 10; 
    } 
} 

class B extends A { 
    public B() { 
     i = 20; 
    } 
} 

public class MainClass { 
    public static void main(String[] args) { 
     A a = new B(); 

     System.out.println(a.i); // will print 20 
}