“成員變量,靜態方法看左邊;非靜態方法:編譯看左邊,運行看右邊。”
意思是:當父類變量引用子類對象時(Fu f = new Zi();),在這個引用變量f指向的對象中,他的成員變量和靜態方法與父類是一致的,他的非靜態方法,在編譯時是與父類一致的,運行時卻與子類一致(發生了復寫)。
例:
class Fu {
intnum = 5;
static void method4() {
System.out.println("fu method_4");
}
void method3() {
System.out.println("fu method_3");
}
}
class Zi extends Fu {
intnum = 8;
static void method4() {
System.out.println("zi method_4");
}
void method3() {
System.out.println("zi method_3");
}
}
class DuoTaiDemo4 {
public static void main(String[] args) {
Fu f = new Zi();
System.out.println(f.num);//與父類一致
f.method4();//與父類一致
f.method3();//編譯時與父類一致,運行時與子類一致
Ziz = new Zi();
System.out.println(z.num);
z.method4();
z.method3();
}
}
輸出結果:
5
fu method_4
zi method_3
8
zi method_4
zi method_3
分析:
Fu f = new Zi();----------首先了解變量F到底是什么,把這句子分2段:Fu f;這是聲明一個變量f為Fu這個類,那么知道了f肯定是Fu類。然后我們f=newZi();中建立一個子類對象賦值給了f,結果是什么??
結果是,擁有了被Zi類函數覆蓋后的Fu類對象----f------。
(上海尚學堂java原創)
也就是說:
只有子類的函數覆蓋了父類的函數這一個變化,但是f肯定是Fu這個類,也就是說f不可能變成其他比如Zi這個類等等(突然f擁有了Zi類特有函數,成員變量等都是不可能的)。所以f所代表的是函數被復寫后(多態的意義)的一個Fu類,而Fu類原來有的成員變量(不是成員函數不可能被復寫)沒有任何變化----------------獲得結論:A:成員變量:編譯和運行都看Fu。
但是f的Fu類函數被復寫了。
獲得結論:B:非靜態方法:編譯看Fu,運行看Zi
對於靜態方法:編譯和運行都看Fu!!
其實很簡單,首先我們要理解靜態情況下發生了什么?
當靜態時,Fu類的所有函數跟隨Fu類加載而加載了。也就是Fu類的函數(是先於對象建立之前就存在了,無法被后出現的Zi類對象所復寫的,所以沒發生復寫,那么獲得:C:靜態方法:編譯和運行都看Fu