JAVA 的繼承機制是一種復用類的技術,從原理上來說,是更好的使用了組合技術,因此要理解繼承,首先需要了解類的組合技術是如何實現類的復用的。
使用組合技術復用類 假設現在的需求是要創建一個具有基本類型,String 類型以及一個其他非基本類型的對象。該如何處理呢?
對于基本類型的變量,在新類中成員變量處直接定義即可,但對于非基本類型變量,不僅需要在類中聲明其引用,并且還需要手動初始化這個對象。
這里需要注意的是,編譯器并不會默認將所有的引用都創建對象,因為這樣的話在很多情況下會增加不必要的負擔,因此,在合適的時機初始化合適的對象,可以通過以下幾個位置做初始化操作:
在定義對象的地方,先于構造方法執行。在構造方法中。在正要使用之前,這個被稱為惰性初始化。使用實例初始化。
繼承 Java 中的繼承由 extend 關鍵字實現,組合的語法比較平實,而繼承是一種特殊的語法。當一個類繼承自另一個類時,那么這個類就可以擁有另一個類的域和方法。
上面的代碼中,展示了繼承語法中的一些特性:
子類可以直接使用父類中公共的方法和成員變量(通常為了保護數據域,成員變量均為私有) 子類中可以覆蓋父類中的方法,也就是子類重寫了父類的方法,此時若還需要調用被覆蓋的父類的方法,則需要用到 super 來指定是調用父類中的方法。子類中可以自定義父類中沒有的方法。可以發現上面兩個類中均有 main 方法,命令行中調用的哪個類就執行哪個類的 main 方法,例如:java Deter。繼承語法的原理 接下來我們將通過創建子類對象來分析繼承語法在我們看不到的地方做了什么樣的操作。
可以先思考一下,如何理解使用子類創建的對象呢,首先這個對象中包含子類的所有信息,但是也包含父類的所有公共的信息。
下面來看一段代碼,觀察一下子類在創建對象初始化的時候,會不會用到父類相關的方法。
通過觀察代碼可以發現,在實例化Cartoon時,事實上是從最頂層的父類開始向下逐個實例化,也就是最終實例化了三個對象。編譯器會默認在子類的構造方法中增加調用父類默認構造方法的代碼。
因此,繼承可以理解為編譯器幫我們完成了類的特殊組合技術,即在子類中存在一個父類的對象,使得我們可以用子類對象調用父類的方法。而在開發者看來只不過是使用了一個關鍵字。
注意:雖然繼承很接近組合技術,但是繼承擁有其他更多的區別于組合的特性,例如父類的對象我們是不可見的,對于父類中的方法也做了相應的權限校驗等。