2013-02-16 44 views
2
class A { 
    int i = 1; 
    int f() { return i; } 
} 
class B extends A { 
    int i = 2; 
    int @Override f() { return -i; } 
} 
public class override_test { 
    public static void main(String args[]) { 
     B b = new B(); 
     A a = (A) b;    // Cast b to an instance of class A. 
     System.out.println(a.i); // Now refers to A.i; prints 1; 
     System.out.println(a.f()); // Still refers to B.f(); prints -2; 
    } 
} 

我想知道爲什麼a.f()仍然指向B.f(),而a.i指向A.i.將子類投射到超類後的調用方法的有趣行爲

在此先感謝!

回答

0

簡單的規則是當你調用一個方法,它將在實例類型(多態),在這種情況下,實例類型爲B,即使引用的類型爲A

當您調用變量時,它將在參考的類型上。

瞭解更多關於Ploymorphism

0

這只是事情是這樣的。以C++術語來說,Java實例方法調用是虛擬的。選擇的方法取決於目標對象的實際類別,而不是其引用的類型。字段引用不是虛擬的,字段的選擇取決於引用的類型。

我一般保持字段私有或保護,並通過方法的工作,而不是直接從外部訪問場

2

在java中字段不是多態這就是爲什麼a.iA.i

雖然a.f()指到B.f(),因爲b是一個對象ob B,儘管您將它轉換爲A這意味着您將只能使用聲明爲0的方法。

但該對象仍然是B類型。

所以,當你訪問一個字段時,它是基於引用類型的,當你訪問方法時它是基於對象類型的