建構子(constructor)
建構子的英文為constructor,中文沒有統一的翻譯,通常稱為「建構子」、「建構式」、「建構元」或「建構函數」、「建構函式」…,都是在說同一個東西。
我們知道一個類別(class)內部定義了成員變數(JAVA的術語稱為成員屬性,或簡稱屬性(attribute))和成員函數(JAVA的術語稱為成員方法,或簡稱方法(method))。也就是說,類別定義了一些具體的屬性和方法,一旦類別做了實體化的動作之後(new關鍵字),就可以產生物件,這個(具體的)物件就會擁有該類別所定義的屬性、並且可以執行該類別所定義的方法。
註:此處先不討論靜態static的情況。
我們以實際的程式碼來說明,先定義一個類別:
重點:
有沒有覺得這樣很麻煩?現在還只是3個學生而已,要填的資料量也不多,如果物件和資料量多一點就會變成枯燥的打字任務,而且程式也會變得又臭又長,可讀性和維護性都會變差。
那有沒有辦法在物件被建立出來的同時,就把這些資料輸入進去呢?也就是讓物件在被創造出來的同時,就一併完成「初始化」的動作。有的,就是本章要介紹的建構子(constructor)。
我們加入建構子的觀念,將以上程式碼改寫如下:
註:以上還用到了「this」變數,讀者可先不理會,待看完「this變數」章節之後就會懂了。
我們在這個類別中多寫了幾列程式碼,用來定義此類別的建構子。於是,我們就可以在從這個類別創造物件時,同時在建構子內輸入引數,這樣被創造出來的物件就會有初始值了,如下:
並且這個建構子還包含一個println()方法,會在螢幕上顯示出該物件的學號、性別和身高。
懂得建構子的觀念後,我們再來回顧上一段程式碼,也就是在還沒定義建構子的那時候,當我們要創造物件時,語法是這樣寫的:
Student 小明 = new Student();
Student 阿華 = new Student();
Student 小美 = new Student();
等號左側代表我們宣告建立一個Student資料型態(類別)的物件小明、阿華和小美,而等號右側的Student()是這個類別的建構子(constructor)。而因為此時我們沒有定義建構子的內容,所以建構子的()內都不寫東西,代表我們只是創造了一個物件,但這個物件裡面的屬性都是空白的,故後續才需要一個一個指定,但這樣不是好的寫法。
註:像這種情況,即使我們沒有定義建構子的內容,JAVA/C++還是會自動「塞」一個建構子到class中,只是你看不見而已,術語叫做「預設建構子」,所以我們還是可以在以new創造物件時呼叫建構子,只不過這時候就不能在建構子的()內填入引數,因為預設建構子是無引數的建構子。
如果我們在class內就先定義好建構子,並於「new」的時候同時在建構子內輸入引數,就能在創造物件時(new關鍵字),同時把初始值賦予給這個物件的屬性(成員變數)。
由於絕大部分的物件導向程式,起手式都是從定義class開始,並從這個class創造物件,讓物件使用「方法」(method)與其他物件互動,所以學會和徹底了解建構子是非常基本且重要的。
有的人或書籍會說建構子是一種特殊的方法(特殊的成員函數),但這麼說並不太對,因為以下三點是建構子(constructor)和方法(method)的不同之處:
因為以上三點差異,所以建構子和方法並不完全相同。話雖這麼說,但其實也不用特別去爭論建構子到底是不是一種特殊的方法,這只是認定的問題,我們學會怎麼用就好了。
建構子的(引數)多載:
我們知道方法(成員函數)可以多載(overload),也就是方法會依照我們給它輸入不同型態、不同個數,甚至不同順序的引數,自動去配對所對應的定義去執行。
同樣的,建構子的引數也可以多載,我們可以在定義建構子的時候就做多個定義,讓建構子在偵測到不同型態、不同個數,甚至不同順序的引數時,自動去尋找對應的定義,對new出來的物件做初始化。
JAVA為了方便我們寫程式,如果只是建構子引數的數量不同,就不用分別寫出它們對應的定義,讓我們節省很多時間。例如以下程式,我們定義了3個引數的建構子,但在以new關鍵字對類別做實體化時,在建構子中各輸入3個、2個、1個引數,甚至無引數都行,還是可以創造出四個狗物件,相當方便。
建構子的(引數)多載(overload),範例的程式碼如下:
public class Dog { // 定義一個Dog類別
String type ; // 宣告字串型態的type
String color ; // 宣告字串型態的毛色
int age ; // 宣告整數型態的年齡
public Dog(String type, String color, int age){ // 定義建構子
this.type = type;
this.color = color;
this.age = age;
}
public static void main(String[ ] args){ // 程式的進入點
Dog dog1 = new Dog(”黃金獵犬”、”金毛”、7); // 建構子的多載
Dog dog2 = new Dog(”台灣土狗”、”黑毛”);
Dog dog3 = new Dog(”米格魯”);
Dog dog4 = new Dog();
}
}