java的多型總結
老畢的"編譯看左邊,執行看右邊"(多型執行)
(對面向物件語言中理解多型、繼承很有幫助~~~)
在多型中,成員變數的特點: 無論編譯和執行,都參考左邊(引用型變數所屬的類)
在多型中,靜態成員函式的特點:無論編譯和執行,都參考做左邊。
在多型中,非靜態成員函式的特點:編譯看左邊,執行看右邊。
老畢在講到多型執行問題時,結合下面的例子,給我們總結了一套口訣:“成員變數,靜態方法看左邊;非靜態方法:編譯看左邊,執行看右邊。”意思是:當父類變數引用子類物件時(Fu f = new Zi();),在這個引用變數 f 指向的變數/方法中,他對成員變數和靜態方法的呼叫與父類是一致的,他呼叫非靜態方法時,在編譯時是與父類一致的(檢視父類有沒有該函式,沒有就會發生編譯錯誤,提示fu 中找不到要呼叫函式),執行時如果子類中發生了複寫就與子類一致。(如果右邊沒有再看左邊。若都沒有才會報錯)
總結1:例項 想要呼叫父類的方法或者成員變數 就需要建立父類的例項化
總結2:成員變數,靜態方法看左邊;非靜態方法:編譯看左邊,執行看右邊
圖片
例:
class Fu
{
int num = 5;
static void show()
{
System.out.println(“fu show()”);
}
void print()
{
System.out.println(“fu print()”);
}
}
class Zi extends Fu
{
int num = 8;
static void show()
{
System.out.println(“zi show()”);
}
void print()
{
System.out.println(“zi print()”);
}
}
class Demo
{
public static void main(String[] args)
{
Fu f = new Zi();
System.out.println(f.num);//與父類一致
f.show();//與父類一致
f.print();//編譯時與父類一致,執行時與子類一致
Zi z = new Zi();
System.out.println(z.num);
z.show();
z.print();
}
}
輸出結果:
5
fu show()
zi print()
8
zi show()
zi print()
個人分析:
Fu f = new Zi();----------首先了解變數F到底是什麼,把這句子分2段:Fu f;這是宣告一個變數f為Fu這個類,那麼知道了f肯定是Fu類。然後我們f=newZi();中建立一個子類物件賦值給了f,結果是什麼??
結果是,擁有了被Zi類函式覆蓋後的Fu類物件----f------。
-------------------------------------------也就是說:
只有子類的函式覆蓋了父類的函式這一個變化,但是f肯定是Fu這個類,也就是說f不可能變成其他比如Zi這個類等等(突然f擁有了Zi類特有函式,成員變數等都是不可能的)。所以f所代表的是函式被複寫後(多型的意義)的一個Fu類,而Fu類原來有的成員變數(不是成員函式不可能被複寫)沒有任何變化----------------獲得結論:A:成員變數:編譯和執行都看Fu。
但是f的Fu類函式被複寫了。--------------獲得結論:B:非靜態方法:編譯看Fu,執行看Zi
對於靜態方法:編譯和執行都看Fu!!
其實很簡單,首先我們要理解靜態情況下發生了什麼?
----------------當靜態時,Fu類的所有函式跟隨Fu類載入而載入了。也就是Fu類的函式(是先於物件建立之前就存在了,無法被後出現的Zi類物件所複寫的,所以沒發生複寫,那麼獲得:C:靜態方法:編譯和執行都看Fu。