• <nav id="wkkge"><strong id="wkkge"></strong></nav>
  • <menu id="wkkge"></menu>
  • Java教程
    Java標識符與關鍵字
    Java變量
    Java數據類型
    Java運算符
    Java控制語句
    Java方法
    Java面向對象
    Java對象的創建和使用
    Java封裝
    Java中static和this
    Java繼承
    Java方法覆蓋和多態
    Java super
    Java基礎練習題

    Java中super關鍵字的使用(在構造方法中)

     

     

    super使用在構造方法中,語法格式為:super(實際參數列表),這行代碼和“this(實際參數列表)”都是只允許出現在構造方法第一行(這一點記住就行了),所以這兩行代碼是無法共存的。“super(實際參數列表)”這種語法表示子類構造方法執行過程中調用父類的構造方法。我們來看一段代碼:

     

    public class People {
    	String idCard;
    	String name;
    	boolean sex;
    	public People(){
    	}
    	public People(String idCard,String name,boolean sex){
    		this.idCard = idCard;
    		this.name = name;
    		this.sex = sex;
    	}
    }

     

    public class Student extends People{
    	//學號是子類特有的
    	int sno;
    	public Student(){
    		
    	}
    	public Student(String idCard,String name,boolean sex,int sno){
    		this.idCard = idCard;
    		this.name = name;
    		this.sex = sex;
    		this.sno = sno;
    	}
    }

     

    public class StudentTest {
    	public static void main(String[] args) {
    		Student s = new Student("12345x","jack",true,100);
    		System.out.println("身份證號" + s.idCard);
    		System.out.println("姓名" + s.name);
    		System.out.println("性別" + s.sex);
    		System.out.println("學號" + s.sno);
    	}
    }

     

    運行結果如下圖所示:

     

    圖14-4:運行結果

     

    我們把上面的代碼片段拿過來放在一起看看:

     

    父類的構造方法:

     

    public People(String idCard,String name,boolean sex){
    	this.idCard = idCard;
    	this.name = name;
    	this.sex = sex;
    }

     

    子類的構造方法:

     

    public Student(String idCard,String name,boolean sex,int sno){
    	this.idCard = idCard;
    	this.name = name;
    	this.sex = sex;
    	this.sno = sno;

     

    你有沒有察覺到子類的構造方法前三行代碼和父類構造方法中的代碼是一樣的?接下來把子類的構造方法修改一下,然后再運行測試程序:

     

    public Student(String idCard,String name,boolean sex,int sno){
    		super(idCard,name,sex);
    		this.sno = sno;
    }

     

    運行結果如下圖所示:

     

    圖14-5:運行結果

     

    通過以上代碼的學習,“super(實際參數列表);”語法表示調用父類的構造方法,代碼復用性增強了,另外一方面也是模擬現實世界當中的“要想有兒子,必須先有父親”的道理。不過這里的“super(實際參數列表)”在調用父類構造方法的時候,從本質上來說并不是創建一個“獨立的父類對象”,而是為了完成當前對象的父類型特征的初始化操作。(或者說通過子類的構造方法調用父類的構造方法,是為了讓張小明身上長出具有他父親特點的鼻子和眼睛,鼻子和眼睛初始化完畢之后,具有父親的特點,但最終還是長在張小明的身上)。

     

    接下來,再來看一段代碼:

     

    public class A {
    	public A(){
    		System.out.println("A類的無參數構造方法執行");
    	}
    }

     

    public class B extends A {
    	public B(){
    		System.out.println("B類的無參數構造方法執行");
    	}
    }

     

    public class C extends B {
    	public C(){
    		System.out.println("C類的無參數構造方法執行");
    	}
    }

     

    public class Test {
    	public static void main(String[] args) {
    		new C();
    	}
    }

     

    運行結果如下圖所示:

     

    圖14-6:super()的測試

     

    通過以上運行結果可以得出以下的等效代碼:

     

    public class A {
    	public A(){
    		//這里調用的是Object類中的無參數構造方法
    		//因為A類的父類是Object
    		super(); 
    		System.out.println("A類的無參數構造方法執行");
    	}
    }

     

    public class B extends A {
    	public B(){
    		super();
    		System.out.println("B類的無參數構造方法執行");
    	}
    }

     

    public class C extends B {
    	public C(){
    		super();
    		System.out.println("C類的無參數構造方法執行");
    	}
    }

     

    運行結果如下圖所示:

     

    圖14-7:super()的測試

     

    通過以上代碼的測試我們得出,當一個構造方法第一行沒有顯示的調用“super(實際參數列表)”的話,系統默認調用父類的無參數構造方法“super()”。當然前提是“this(實際參數列表)”也沒有顯示的去調用(因為super()和this()都只能出現在構造方法第一行,所以不能并存)。我們可以通過以下程序再次測試一下:

     

    public class A {
    //有參數構造方法定義之后
    //系統則不再提供無參數構造方法
    	public A(String s){
    	}
    }

     

    public class B extends A {
    	public B(){
    	}
    }

     

    編譯報錯了:

     

    圖14-8:編譯報錯信息

     

    以上程序為什么會編譯報錯呢?原因是B類的構造方法第一行默認會調用“super()”,而super()會調用父類A的無參數構造方法,但由于父類A中提供了有參數構造方法,導致無參數構造方法不存在,從而編譯報錯了。所以在實際開發中還是建議程序員將無參數構造方法顯示的定義出來,這樣就可以避免對象的創建失敗了。

     

    另外,通過以上內容的學習,還可以得出這樣的結論:在java語言當中無論是創建哪個java對象,老祖宗Object類中的無參數構造方法是必然執行的。

     

    接下來我們再來看一下:一個java對象在創建過程中比較完整的內存圖是如何變化的,請先看以下代碼:

     

    public class People {
    	String name;
    	boolean sex;
    	public People(String name,boolean sex){
    		this.name = name;
    		this.sex = sex;
    	}
    }

     

    public class Worker extends People {
    	//子類特有的工資屬性
    	double salary;
    	public Worker(String name,boolean sex,double salary){
    		super(name,sex);
    		this.salary = salary;
    	}
    }

     

    public class WorkerTest {
    	public static void main(String[] args) {
    		Worker w = new Worker("jack",true,10000.0);
    		System.out.println("姓名:" + w.name);
    		System.out.println("性別:" + w.sex);
    		System.out.println("工資:" + w.salary);
    	}
    }

     

    運行結果如下圖所示:

     

    圖14-9:運行結果

     

    以上程序創建Worker對象時構造方法的執行順序是:

     

    ● 先執行Object類的無參數構造方法;

     

    ● 再執行People類的構造方法;

     

    ● 最后執行Worker類的構造方法;

    注意:雖然執行了三個構造方法,但是對象實際上只創建了一個Worker。

     

    以上程序的內存結構圖是這樣變化的:

     

    圖14-10:程序執行內存圖

     

    通過以上內容的學習,super()的作用主要是:第一,調用父類的構造方法,使用這個構造方法來給當前子類對象初始化父類型特征;第二,代碼復用。

     

    全部教程
  • <nav id="wkkge"><strong id="wkkge"></strong></nav>
  • <menu id="wkkge"></menu>
  • 面对面棋牌游戏