• 沒有找到結果。

如果在產生物件實體時,能夠自動幫我 們呼叫某個特定函式,進行某些初始化 動作,不是使得設計程式方便多了嗎?

是的,Java如同其他的物件導向語言一般,也考 慮到了這一點,因此可以在建構子中來完成這些 事情。

建構子(Constructor)又稱建構函式,它 是生成物件實體時會自動執行的函式。

由於它很特別,因此定義語法與一般成 員函式有些不同,語法如下:

7.6 建構子

73

語法說明:

(1)建構函式名稱一定要和類別名稱相同。

(2)不可加上回傳值型態,連void也不行。如果加上回傳值型態(

含void)則不是建構函式,如此就不會在物件實體產生時自動執 行。

(3)沒有任何修飾字。

(4)建構函式只能被new運算子於產生物件實體時自動呼叫,無法 讓物件的一般函式自由呼叫。

(5)封裝等級一般宣告為public等級。如果宣告為private等級,

則只有其他建構函式可以呼叫它。無法被new自動呼叫。

【觀念範例7-4】:使用建構函式改寫範例7-2,使其成為建構函式以 便自動進行成員變數的初始化。

範例7-4:ch7_04.java(隨書光碟 myJava\ch07\ch7_04.java)

[封裝等級] 建構函式名稱(參數串) //建構函式名稱就是類別名稱 {

……建構函式內容……

}

7.6 建構子

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

/* 檔名:ch7_04.java 功能:建構函式 */

package myJava.ch07;

import java.lang.*;

public class ch7_04 //主類別 {

public static void main(String args[]) {

CMyClass X = new CMyClass(1); //自動呼叫建構函式 CMyClass Y = new CMyClass(2); //自動呼叫建構函式 X.addVar(10); //在X物件上,執行addVar成員函式 System.out.print("物件X\t");

X.showVar();

System.out.print("物件Y\t");

Y.addVar(5); //在Y物件上,執行addVar成員函式 Y.showVar();

System.out.print("物件Y\t");

Y.addVar(3); //在Y物件上,執行addVar成員函式 Y.showVar();

} }

7.6 建構子

75

執行結果:

範例說明:

第10行,宣告物件變數X並產生實體,當實體產生時,

就會自動立刻執行該類別的建構函式,也就是執行第 29~32行程式。第11行亦同理。如果將第11行傳入的引 數改為『1』,則執行結果同範例7-2。

26 27 28 29 30 31 32 : 46

class CMyClass {

public CMyClass(int i) {

Var=i;

}

...同範例7-2的第36~48行...

}

物件X Var=11 物件Y Var=7 物件Y Var=10

建構子名稱需與類別名稱相同。

建構子

7.6 建構子

上一章所提到的多載功能不但可以應用於一 般成員函式,也可以應用於建構函式。

程式可藉由定義多個不同參數(或不同資料型態)的 建構函式,提供物件實體初始化時更大的彈性。

【觀念範例7-5】:多載建構函式,使得在物件實體 產生時,可以依照不同情況執行不同的建構函式。

範例7-5:ch7_05.java(隨書光碟 myJava\ch07\ch7_05.java)

7.6.1建構子的多載

77

7.6.1建構子的多載

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

/* 檔名:ch7_05.java 功能:建構函式的多載 */

package myJava.ch07;

import java.lang.*;

public class ch7_05 //主類別 {

public static void main(String args[]) {

CMyClass X = new CMyClass();

CMyClass Y = new CMyClass(5,40);

CMyClass Z = new CMyClass(20.2,30.6);

X.showVar();

Y.showVar();

Z.showVar();

} }

class CMyClass {

public double VarA;

private double VarB;

呼叫第24行的建構子

呼叫第29行的建構子

呼叫第34行的建構子

執行結果:

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

public CMyClass() //定義無參數的建構函式

{

VarA=10;

VarB=10;

}

public CMyClass(int a,int b) //定義兩個整數參數的建構函式 {

VarA=a;

VarB=a+b;

}

public CMyClass(double a,double b) //定義兩個浮點數參數的建構函式 {

VarA=a;

VarB=a*b;

}

public void showVar() {

System.out.println("VarA=" + VarA);

System.out.println("VarB=" + VarB);

} }

7.6.1建構子的多載

VarA=10.0 VarB=10.0 VarA=5.0 VarB=45.0 VarA=20.2 VarB=618.12

79

範例說明:

(1)第24~38行是3個建構函式的定義,其署名不相同,

符合多載的規定。並且其內的建構內容也可以不同。

(2)第10行產成X物件實體,由於沒有引數,所以會執行 第24~28行的建構函式。第11行生成Y物件實體,由於有 2個int整數引數,所以會執行第29~33行的建構函式。

第12行生成Z物件實體,由於有2個double浮點數引數,

所以會執行第34~38行的建構函式。

7.6.1建構子的多載

如果您未定義建構函式,則Java編譯器會自動產 生一個內建的預設建構函式(Default

Constructor)到程式中,函式內容為空,也沒有 參數,格式如下:

正因為有此預設的建構函式,所以在之前的範例中,有 時我們並未定義建構函式,但編譯仍不會出錯。

但是如果您已經定義了一個以上的建構函式時,Java編 譯器便會認定您已經準備好所有的建構函式,此時將不 會再產生預設建構函式,而若您沒有建立一個無參數的 建構函式,卻又於產生物件實體時不傳入引數,則會發 生錯誤,請見以下的範例。

7.6.2 預設的建構子

public 類別名稱() //預設的建構函式 {

}

81

【觀念範例7-6】:取消預設建構函式的注意事項 範例7-6:ch7_06.java(隨書光碟

myJava\ch07\ch7_06.java)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

/* 檔名:ch7_06.java 功能:預設的建構子 */

package myJava.ch07;

import java.lang.*;

public class ch7_06 //主類別 {

public static void main(String args[]) {

CMyClass X = new CMyClass(5,40); //實體產生有兩個整數引數 //CMyClass Y = new CMyClass();

X.showVar();

//Y.showVar();

} }

7.6.2 預設的建構子

無法找到對應的建構子 VarA=5

VarB=45

執行結果

範例說明:

第11行的註解如果 取消,則會發生錯 誤,因為預設的建 構函式並不會產生

,故找不到對應的 建構函式可執行。

所以在定義建構函 式時,應該先定義 一個無參數的建構 函式(函式內容可 以暫時為空),以 避免這樣的狀況。

7.6.2 預設的建構子

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

class CMyClass {

public int VarA;

private int VarB;

public CMyClass(int a,int b) //定義兩個整數參數的建構函式 {

VarA=a;

VarB=a+b;

}

public void showVar() {

System.out.println("VarA=" + VarA);

System.out.println("VarB=" + VarB);

} }

小試身手7‐1

依照範例7‐6的說明,將第11、13行的註解取消,並加入無參數的建構函式(函式 內容為空),使得可編譯並執行成功。

小試身手7‐1

依照範例7‐6的說明,將第11、13行的註解取消,並加入無參數的建構函式(函式

內容為空),使得可編譯並執行成功。

83

在Java中,想要釋放物件實體,只要將 所有參考到該物件實體的物件變數都設 為null或指向其他實體,則Java的回收 機制就會在一段時間後自動回收該物件 實體的記憶體空間。

而其他程式語言(例如C++)則提供了delete與解 構函式,需要使用者手動關心物件釋放的後續動 作。

7.6.3回收物件實體

在呼叫函式時,引數也可以是物件

在前面的範例中,我們曾經示範過傳遞字串物件

。當時我們曾經提及,傳遞字串物件,事實上採 用的是傳「參考值」呼叫

因為物件變數本身是一個參考而非實體。

當我們要傳遞一個自行定義的類別所宣告的物件 變數時,同樣採用的是傳「參考值」呼叫,因此

,呼叫端與被呼叫端可以共用一個物件實體。

在下面這個範例中,我們將傳遞物件,並且將使

用成員函式多載進行不同資料型態的加法。

相關文件