前言
動態分派和靜態分派機制是Java多態實現的原理。本文將針對這兩種機制進行淺析。
靜態分派
靜態分派機制最典型的代碼示例如下
void test() {
Father father = new Son(); //靜態分派
print(father);
}
void print(Father father) {
System.out.println("this is father");
}
void print(Son son) {
System.out.println("this is son");
}
這段代碼執行完成以后會輸出this is father。之所以會輸出這樣一個結果,原因就是此處的多態實現是靜態分派的。在編譯階段,由於father變量類型被聲明為Father。因此在編譯階段就已經確定了調用的是參數為Father的方法,與具體的實例化對象無關。
動態分派
動態分派機制最典型的代碼示例如下
void test() {
Father father = new Son(); //靜態分派
father.name(); //動態分派
}
class Son extends Father {
void name(){
System.out.println("son");
}
}
class Father {
void name(){
System.out.println("father");
}
}
這里我們聲明了靜態類型Father,但是實際上我們調用name方法的時候,輸出的卻是son。這里就牽扯到一個動態分派的問題,對於方法重寫,Java采用的是動態分派機制,也就是說在運行的時候才確定調用哪個方法。由於father的實際類型是Son,因此調用的就是Son的name方法。
單分派與多分派
靜態分派是多分派的,動態分派是單分派的。
多分派是指在靜態分派的過程中需要考慮兩步:
1、判斷靜態類型是Father還是Son
2、判斷方法參數是Father還是Son
綜合上述兩個因素(宗量),才能確定調用哪個方法。
而動態分派由於使用的時候已經確定了參數類型,所以不需要對參數類型進行判斷,只需要對變量類型進行判斷即可。比如在上述例子中,我們已經通過靜態分派,確定了調用的是無參的name方法,這時候我們就只需要考慮father的實際類型是Father還是Son即可。因此動態分派是單分派的。
總結
在Java多態的兩種常見用法中,方法重載使用的是靜態分派機制,而方法重寫使用的是靜態分派機制。這也就導致了,方法重載調用的時候是根據變量的靜態類型來決定調用哪個方法。而方法重寫的時候,則是根據變量的實際類型來決定調用哪個方法。