Java核心——繼承

繼承


extends:譯爲擴展、延伸之意。在java中,繼承是在面向對象的基礎上提出的概念。面向對象講的是將同類型事物抽象出來,然後封裝成類。類相當於是一種模板,根據這種模板產生具體的實例對象,而實例對象則負責完成具體的業務邏輯。在類型的抽象過程中,有很多屬性和方法是通用的,即很多類都具有相同的部分。所以我們需要將這些相同的部分抽離出來,作爲基類,子類只要繼承了基類,則自動擁有了那些公共的屬性。這樣就可以減少代碼重複,使代碼更加簡潔,邏輯更加清晰。

java中所有的類都默認繼承自Object類,Object類中包含equals和toString()方法。equals默認比較引用是否相等,而toString默認打印了對象的hashcode信息。通常在使用時我們都會重寫這兩個方法。如果查看源碼會發現不止這兩個方法,會有很多native方法。native方法查看不到具體的方法實現,native方法通常是其他語言編寫的,使其效率更高。

java默認爲單繼承,一個子類只能繼承一個父類。但可以是多實現,即一個子類可以實現多個接口。在java8中新增了默認方法。使得在接口中也可以有方法實現,使其可以完成多繼承的功能。

public interface Vehicle {
   default void print(){
      System.out.println("我是一輛車!");
   }
}

子類繼承父類後,就已經包含了父類的所有屬性和方法。類中使用this關鍵字來表示對自身的引用,之前也有提到,我們代碼編寫時定義的類其實只是一個模板,這個模板定義了這個類的所有元信息,通過這些信息我們就可以實例化出對象,而Class信息在類加載過程中,會被存儲到內存模型中的方法區中,也是我們使用反射時獲取的數據來源。這裏的this並不是指我們編寫的這個類,而是具體產生的實例對象。我們知道java中new產生的對象都分配在堆上,所以this其實就是指向這個對象實例在堆上的內存地址。我們聲明瞭一個類模板信息,但是可以new出很多個對象,this在不同的對象實例中就會有不同的值,而我們定義類時使用的關鍵字更像是一個佔位符。

繼承了父類後,不僅有this關鍵字指向自身,也會有super關鍵字指向父類。剛纔分析到this是指向堆內存的一個引用,同理super也是這樣的一個引用。由此可以說明,在實例化子類的同時,也實例化了一個父類對象。下面是類初始化的順序:

  1. 父類靜態成員和靜態初始化塊
  2. 子類靜態成員和靜態初始化塊
  3. 父類實例成員和實例初始化塊
  4. 父類構造方法
  5. 子類實例成員和實例初始化塊
  6. 子類構造方法

所以子類擁有了一個父類的引用,所以我們可以通過這個引用拿到父類的所有信息。所以繼承雖然名稱叫做繼承,但其實可以看做是使用了組合的方式,將父類引用作爲子類的一個屬性,從而實現了複用和擴展。

如果使用static修飾的方法中,並不存在this和super的引用。因爲static修飾的方法屬於類的基本信息,把類信息作爲模板理解,模板是記錄了類的元數據,所有類在實例化的時候都是通過這些元數據進行初始化。所以只要模板中聲明瞭,那麼所有的對象實例中自然也就包含了這些函數。並且Class信息存儲在內存模型的方法區中,屬於線程共享的區域。所以我們可以直接訪問方法區拿到static修飾的類信息,沒有必要通過引用去堆中找到對應的內存塊,然後拿到對應的數據或者方法,因爲他們都是一樣的。更加沒有必要分辨this還是super,因爲這些基本信息在類模板中早已經確定了。

談到了繼承就會有兩個概念需要區分:重載與重寫。子類得到父類的所有數據後,如果需要對其功能進行加強或者修改,就需要重新編寫這個方法。但其方法簽名(包括方法名稱、參數類型、參數個數,返回值不屬於方法簽名的一部分)不改變,僅僅是修改方法體。這時候子類中就擁有了兩個方法簽名完全相同的方法,一個來自父類,一個是自己重新定義的。在使用時,來自父類的方法會隱藏起來,只有子類重新定義的方法纔會生效。這裏就涉及到了多態的相關原理。所以重寫指的是重新編寫新方法替換掉繼承下來的方法。而重載其實和繼承並沒有任何關係,只是因爲名稱相近所以在這裏進行區分。有時候同一件事情會有多種解決方案,但是解決這個事情的過程我們卻只有一個命名。比如在超市結賬,買一件商品叫做結賬,買兩件商品也叫結賬,買不同種類的商品還是叫結賬。在程序中的體現就是爲了滿足各種情況,我們編寫了各自不同的處理方法,但是它們的名稱相同,但方法簽名不同,也就是參數類型,參數個數不同。這些名稱相同的方法就構成了重載。因爲名稱相同所以可能對我們編程人員可能造成困擾,而在計算機眼裏,並不是通過名稱來區分方法的不同,而是通過方法簽名,所以這些名稱相同的方法,在處理過程中自動就被識別成了不同的方法,根本不會有任何的阻礙。所以爲什麼要把不同的方法命名成一樣的名字呢?除了更加符合現實中的習慣,感覺沒有任何意義。

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