多態:事物的多種體現形態
父類的引用指向了自己的子類的對象。
前提:類與類之間有關系,要麼繼承或實現。
好處:提高了代碼的擴展性
弊端:但是只能使用父類的引用指向子類和父類同樣的方法。
類型轉換:向上轉型 向下轉型
instanceof 用於判斷對象是屬於哪種類型。
多態(父類的引用指向子類對象)在代碼中的特點(注意事項):
在多態中非靜態成員函數的特點:
在編譯時期: 參閱引用型變量所屬類中是否有調用的方法。如果有,編譯通過,否則編譯失敗。
在運行時期: 參閱對象所屬的類中是否有調用的方法。
簡單的總結:成員函數在多態調用時,編譯看左邊,運行看右邊。
在多態中,非靜態成員變量的特點:
無論編譯和運行,都參考左邊(引用型變量所屬的類)
在多態中,靜態成員變量/函數的特點:
無論編譯和運行,都參照左邊。
java對非靜態方法的調用是采取動態綁定(運行時才判斷)的方法,
對靜態成員、屬性的調用是采取靜態綁定(編譯時就判斷)的方法。
---------------------示例代碼----------------------------------------
class Fu{ public String name = "Fu"; public static String address= "Fu address"; public void method1(){ System.out.println("Fu method1"); } public void method2(){ System.out.println("Fu method2"); } public static void method4(){ System.out.println("static Fu method4"); } } class Zi extends Fu{ public static String address= "Zi address"; public String name = "Zi"; public void method1(){ System.out.println("Zi method1"); } public void method2(){ System.out.println("Zi method2"); } public void method3(){ System.out.println("Zi method3"); } public static void method4(){ System.out.println("static Zi method4"); } public void method5(){ System.out.println(name); } public void method6(){ System.out.println(super.name); } public void method7(){ System.out.println(name); } } public class Test{ public static void main(String args[]){ /*關於非靜態/和靜態函數的演示*/ //Fu z = new Zi(); //z.method3();//編譯會報錯 //z.method2();//Zi method2 /*為什麼會出現下面的這種情況? 因為靜態方法是靜態綁定好的, 無論是在什麼情況在最初的時候就已經在靜態方法區把靜態方法和類綁在一起,所以靜態方法不存在覆蓋 不管引用指向哪個對象不沒有用。 而非靜態方法是在new對象的時候把非靜態方法和對象綁定一起,通過對象去調用非靜態方法。 */ //z.method4(); //static Fu method4 //Zi z1 = new Zi(); //z1.method4();//static Zi method4 /*成員變量的演示*/ Zi z2 = new Zi(); System.out.println(z2.name);//Zi //(在堆內存中同時存在兩個變量, //那麼會先找定義引用的那個類的那個變量值 和 方法不同) Fu z4 = new Zi(); System.out.println(z4.name);//Fu /*為什麼會出現這種情況? 在非靜態成員變量中,對象的引用去取成員變量是根據左邊的類去找相對應的值 在靜態成員變量中是根據靜態綁定的原理一樣一開始就把類和靜態成員綁定在一起。 不管自己指向哪個對象 靜態的成員或方法都是直接和類進行綁定在一起稱之為靜態綁定 java對非靜態方法的調用是采取動態綁定(運行時才判斷)的方法, 對靜態成員、屬性的調用是采取靜態綁定(編譯時就判斷)的方法。 */ //Fu z3 = new Zi(); //System.out.println(z3.address);//Fu address //Zi z4 = new Zi(); //System.out.println(z4.address);//Zi address } }