JAVA 編譯時多態 運行時多態

java多態是指同名符號在不同情況下具有不同的解釋性。可分爲編譯時多態運行時多態

運行時多態

運行時多態由函數重寫產生,僅發生在函數重寫時,以以下程序爲例:


public class Test {
	public static void main(String[] args) {
		A a = new A();
		B b = a;
		b.p(10);
	}
}
class B{
	
	public void p(double i) {
		System.out.println("B"+i*2);
	}
}
class A extends B{
	
	public  void p(double i) {
		System.out.println("A"+i);
		}
}

此時A中的p函數對父類的p函數進行了重寫,因此對於指向子類A實例的父類型引用b,在調用重寫函數時,需要選擇到底調用A中p函數還是B中的p函數,選取原則是採用動態綁定的原則:

假設,對象o是類C1的實例,其中C1是C2的子類,C2是C3的子類,那麼o也是C2,C3的實例。如果對象o調用一個方法p,JVM會依次在類C1,C2,C3中查找方法p的實現,直到找到爲止link

先看子類實例對應的子類型A中是否有此函數,存在的話直接調用,否則的話看其直接父類是否含有。
因此直接調用A中的p函數,輸出結果爲:
在這裏插入圖片描述

編譯時多態

其主要是由函數重載產生的。以以下程序爲例:


public class Test {
	public static void main(String[] args) {
		A a = new A();
		B b = a;
		b.p(10);
	}
}
class B{
	
	public void p(double i) {
		System.out.println("B"+i*2);
	}
}
class A extends B{
	
	public  void p(int i) {
		System.out.println("A"+i);
		}
}

此程序與第一個程序不同之處在於子類A中的p函數不是對父類p函數的重寫,只是進行了重載, 因此在進行函數調用時,不再符合運行時多態中的動態綁定原則,進行編譯時多態(靜態綁定),編譯階段即可確定調用引用對象對應的類B中的p函數。
此處我們的調用的p函數中的傳入的參數爲int類型,並且指向的子類實例a中的p函數也是int類型的參數,非常具有迷惑性,但此時並未發生重寫,A和B中的p函數本質還是不同的,僅在編譯時就能確定只能調用類B中的p函數。
運行結果如圖:
在這裏插入圖片描述

屬性及static函數下的多態

本小節參考鏈接:link
對於static方法 不能進行重寫 只能重載/繼承/隱藏
同樣對於屬性,只能被隱藏 不能被覆蓋/重寫
因此,均不能發生運行時多態,運行時多態僅重寫時發生。
因此以下程序不能發生運行時多態,僅在編譯時即可確定所要調用的函數和屬性。


public class Test {
	public static void main(String[] args) {
		A a = new A();
		B b = a;
		System.out.println(b.type);
		b.p(10.0);
	}
}
class B{
	String type = "B";
	public static void p(double i) {
		System.out.println("B"+i*2);
	}
}
class A extends B{
	String type = "A";
	public static void p(double i) {
		System.out.println("A"+i);
		}
}

運行結果:
在這裏插入圖片描述

更多

關於接口的多態與上述類似,具體參考鏈接:link

總結

主要對java中的多態進行了總結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章