您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Java繼承構造器怎么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
初始化基類
前面提到,繼承是子類對父類的拓展。《Thinking in Java》中提到下面一段話:
當創建一個導出類的對象時,該對象包含了一個基類的子對象。這個子對象與你用基類直接創建的對象是一樣的。二者區別在于,后者來自于外部,而基類的子對象被包裝在導出類的對象內部。
我們在創建子類對象時,調用了父類的構造器,甚至父類的父類構造器。我們知道,構造器用于創建對象,那么突然產生疑惑:關于創建一個子類對象時,是否會先創建父類對象?
經過查找資料,得出結論:
并沒有。在創建子類對象時,會把父類的成員變量和方法加載進內存,既然要加載,便調用父類構造器看看這些數據是如何進行初始化的,僅此而已,并不是創建了父類的對象。
所以,可以看作,子類對象中包含著父類的子對象。我們知道,對象的初始化是至關重要的。那么,這個父類的子對象如何正確初始化呢?對了,就是接下來要說的:在構造器中調用基類構造器來執行初始化。注意:子類并不能繼承父類的構造器,只是單純調用了基類構造器中的初始化代碼。
默認構造器
先看一段簡單的測試代碼:
package com.my.pac13;/*繼承中的構造*/public class Person { Person(){ System.out.println("Person()"); }}class Student extends Person{ Student(){ System.out.println("Student()"); }}class PrimaryStudent extends Student{ PrimaryStudent(){ //super(); System.out.println("PrimaryStudent()"); } public static void main(String[] args) { //創建了PrimaryStudent對象 new PrimaryStudent(); }}/* Person() Student() PrimaryStudent()*/
關于構造器,我們前面提到,任何沒有顯式構造器的類都存在著一個無參數的默認構造器。我們上面的例子在默認構造器中加入了打印輸出,以便理解。
可以看到的是:
在創建PrimaryStudent時,他的直接父類Student和間接父類Person中的構造器都被調用了,而且可以看到,是"自上而下"的。父類在子類構造器可以訪問它之前,就已經完成了初始化的操作。
若子類沒有顯式調用父類的構造器,則自動調用父類的默認(無參)構造器。
帶參數的構造器
前面的代碼中,每個類都含有默認的構造器,創建子類對象時,是自上而下,且子類會默認調用父類的無參構造器。那么,假設父類正好沒有無參構造器或者你正想調用父類的帶參構造器,這時就需要我們的super關鍵字。(super關鍵字之后還會進行總結)
我們直接在原來的基礎上稍作修改,并進行測試。
package com.my.pac13;/*調用基類構造器是子類構造器中要做的第一件事*/public class Person { //沒有默認構造器 Person(String name){ System.out.println("Person()\t"+name); }}class Student extends Person{ //也沒有默認構造器,且用super顯式調用 Student(String n){ //super關鍵字調用父類的構造器 super(n); System.out.println("一參數Student\t"+n); } Student(String n,String m){ //this關鍵字調用同一類中重載的構造器 this(n); System.out.println("二參數student()\t"+m); }}class PrimaryStudent extends Student{ //隱式調用父類構無參數構造器,但是父類沒有,所以要用super顯式調用 PrimaryStudent(){ //沒有下面的語句會報錯 super("hello"); System.out.println("PrimaryStudent()"); }}class ExtendsTest{ public static void main(String[] args) { new Person("the shy"); System.out.println("***********"); new Student("rookie"); System.out.println("***********"); new Student("the shy","rookie"); System.out.println("***********"); new PrimaryStudent(); System.out.println("***********"); }}/*Person() the shy***********Person() rookie一參數Student rookie***********Person() the shy一參數Student the shy二參數student() rookie***********Person() hello一參數Student helloPrimaryStudent()*********** */
this是正在創建的對象,用于調用同一類中重載的構造器,可以參看我之前的文章:Java關鍵字之this。 super在調用構造器時,使用方法和this相似。(但super和this本身有本質的不同,super并不是一個對象的引用!!!) super和this語句都必須出現在第一行,也就是說一個構造器中只能有其中之一。
子類調用父類構造器
無論是否使用super語句來調用父類構造器的初始化代碼,子類構造器總是會事先調用父類構造器!這是一定要記住的!
子類構造器A在第一行顯式使用super調用父類構造器B,格式super(參數列表),根據參數列表選擇對應的父類構造器。
//父類 Person(String name){ System.out.println("Person()\t"+name); }//子類 Student(String n){ //super關鍵字調用父類的構造器 super(n); System.out.println("一參數Student\t"+n); }
子類構造器A先用this調用本類重載的構造器B,然后B調用父類構造器。
//父類 Person(String name){ System.out.println("Person()\t"+name); }//子類Student(String n){ //super關鍵字調用父類的構造器 super(n); System.out.println("一參數Student\t"+n); }Student(String n,String m){//this關鍵字調用同一類中重載的構造器 this(n); System.out.println("二參數student()\t"+m);}
子類構造器中沒有super和this時,系統會隱式調用父類的無參構造器,要是沒有無參的,那就報錯。
//隱式調用父類構無參數構造器,但是父類沒有,所以要用super顯式調用PrimaryStudent(){//沒有下面的語句會報錯 super("hello"); System.out.println("PrimaryStudent()");}
綜上所述:
當調用子類構造器對子類對象進行初始化時,父類構造器總會在子類構造器之前執行。甚至,父類的父類會在父類之前執行……一直追溯到所有類的超類Object類的構造器。
感謝各位的閱讀!關于“Java繼承構造器怎么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。