其實Java繼承中,成員變數(包括靜態變數,執行個體變數,常量)沒有覆蓋(override)一說,應該叫隱藏(hidden)。override只針對方法來說的。
當成員變數為private時,其他類不能直接存取到,只能通過非private方法
訪問,因此直接按照分析方法的思路分析,如該方法是否有覆蓋,該方法是否是靜態方法。
當成員變數為static時,即靜態變數,在類載入過程中就分配了記憶體,因此只與訪問的變數類型有關。
class Super {
static String v = "Super";
}
class Sub extends Super {
static String v = "Sub";
public static void main(String[] args) {
Sub sub = new Sub();
System.out.println(sub.v); // 變數sub屬於Sub類型,因此輸出Sub
Super sooper = new Super();
System.out.println(sooper.v); // 變數sooper屬於Super類型,因此輸出Super
Super sb = new Sub();
System.out.println(sb.v); // 這裡雖然new了一個Sub對象,但使用Super類型的變數sb指向它,(可以認為把Sub對象強轉為了Super類型),因此輸出的應該是Super
}
當成員變數為非private時(預設,protected,public),只與訪問的變數類型有關。
把上例中成員變數v的static變為public:
class Super {
public String v = "Super";
}
class Sub extends Super {
public String v = "Sub";
public static void main(String[] args) {
Super sb = new Sub();
System.out.println(sb.v); // 這裡也是輸出Super
}
這裡如果要追問一步:為什麼成員變數為public時,也只與訪問的變數類型有關?
用“子類的同名變數只是隱藏(hidden)了父類的同名變數”來回答覺得只是從形式上回答了。
Super sb = new Sub() 這裡有個隱式強制轉換,顯式寫就是:
Super sb = (Super)new Sub();
因此問題轉到強制轉換:
System.out.println(((Super)new Sub()).v);
1. 強制轉換怎麼個轉法,能把明明屬於子類對象的執行個體變數v的值轉為父類對象的Super?
2. 強制轉換怎麼處理重寫方法?
(知其然不知其所以然)待...
2010.10.26
當調用子類建構函式構建子類對象的時候,必然會先調用父類的建構函式,即構建一個父類對象(怎麼得到這個對象?),因此父類的成員(變數和方法)也會被構建。
如果存在同名,記憶體中將會同時存在父類的同名成員和子類的同名成員。由於Java的多態性只針對方法來說的,成員變數不存在多態,因此成員變數只與訪問的變數類型有關,而方法的調用遵從多態的規則。