重載與重寫(overload and override)

在java編程中經常會遇到重載和重寫,剛接觸java的時候對這對概念比較懵比,也不能理解其中的區別,後來在逐漸的學習中更加深刻的理解了其中的原理。哎,說來還是基礎知識學的不紮實,這些都是大學期間偷懶欠下的帳。

(一)簡單理解

1.重載是在一個類中有多個名稱一樣的方法,需要根據參數來辨識運行時使用哪個方法。在java中同一個類的同名方法的重載僅依賴(1)參數類型、(2)參數個數、(3)參數順序三者決定。與返回類型,函數修飾符都無關。

2.重寫是多個類繼承於同一父類,並同時實現了父類的方法,這時我們在利用父類上轉型引用子類並調用接口時,jvm會幫我們執行子類實現的方法邏輯。舉個栗子如下:

class Animal{
   public void move(){
      System.out.println("動物可以移動");
   }
}
 
class Dog extends Animal{
   public void move(){
      System.out.println("狗可以跑和走");
   }
}
 
public class TestDog{
   public static void main(String args[]){
      Animal a = new Animal(); // Animal 對象
      Animal b = new Dog(); // Dog 對象
      a.move();// 執行 Animal 類的方法
      b.move();//執行 Dog 類的方法
   }
}

(二)深入理解

java代碼在經過javac編譯後成爲class文件,然後會通過類加載器加載進入內存。加載類文件的過程是由虛擬機外部用戶自定義的類裝載器實現的,我們常用的就是tomcat,tomcat會將class類文件裝載進內存,然後由虛擬機進行驗證、準備、解析、初始化等操作。class文件中包含邏輯代碼生成的字節碼及很多常量池引用組成的元數據。我們在進行方法調用時,實際上目標方法在class文件中就是一個對常量池的符號引用。們需要將這個符號引用轉爲直接引用,這個過程是jvm在解析過程中實現的。我們的重載和重寫就是從解析開始的,接下來我們仔細介紹類的解析及方法的分派過程。

(1)方法調用的解析過程
我們代碼中對外部類方法的調用,一開始都是簡單的符號引用,虛擬機在類加載階段會自動幫我們進行對符號引用的解析。這個過程可能在類加載期進行,也可能在運行時進行,主要是爲了實現java的動態分派,這個之後說。類加載階段的解析只能針對類的靜態方法、私有方法和final方法進行,因爲這些方法在運行期都是不會發生變化的,其他類型的方法可能被子類繼承並重寫,我們無法在類加載時就確定其直接引用。

(2)方法的分派
方法的分派包含靜態分派和動態分派,重載出現在靜態分派的過程中,而重寫出現在動態分派的過程中。
1.當我們的方法調用在解析過程中找到對應的類後,發現對應的類中有很多同名的方法,這時會根據方法調用時使用的參數類型(稱爲靜態類型)來判定使用哪個函數,然後將依賴類進行加載和初始化,並將符號引用轉爲這個類方法的內存地址,這個過程就叫做靜態分派。
2.當程序運行後,在方法調用的解析過程中發現代碼聲明的類和運行時引用類不同時,會根據實際引用類的地址去尋找實際引用類的方法列表中尋找是否有相應方法,這個過程叫做動態分派,例如有個Son類繼承了父類Father類,並實現了父類的run方法,然後我們執行 Father sonRun = new Son(); sonRun.run();這個過程便是動態分派的過程,動態分派只能在運行期,不能根據靜態類型(Father類)確定方法的內存地址,只能在在操作數棧中找到實際類型。

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