# 建構子(constructor) 建構子(constructor) 建構子的英文為constructor,中文沒有統一的翻譯,通常稱為「建構子」、「建構式」、「建構元」或「建構函數」、「建構函式」…,都是在說同一個東西。 我們知道一個類別(class)內部定義了成員變數(JAVA的術語稱為成員屬性,或簡稱屬性(attribute))和成員函數(JAVA的術語稱為成員方法,或簡稱方法(method))。也就是說,類別定義了一些具體的屬性和方法,一旦類別做了實體化的動作之後(new關鍵字),就可以產生物件,這個(具體的)物件就會擁有該類別所定義的屬性、並且可以執行該類別所定義的方法。 註:此處先不討論靜態static的情況。 我們以實際的程式碼來說明,先定義一個類別: ```bash= class Student { // 定義一個類別,類別名稱為Student(學生) private: String studentID; // 宣告字串型態的學生證號 String gender; // 宣告字串型態的性別 int height; // 宣告整數型態的身高 public: int walk() // 定義此類別的方法walk() { 此方法的實作程式碼 } void say() // 定義此類別的方法say() { 此方法的實作程式碼 } 以上我們把Student這個類別定義好了,接下來我們要創造(具體的)學生物件,JAVA告訴我們語法要這麼寫: Student 小明 = new Student(); Student 阿華 = new Student(); Student 小美 = new Student(); 然後我們再把三人的基本資料填上去: 小明 . studentID = “L25247845”; 小明 . gender = “男”; 小明 . height = 175 ; 小華 . studentID = “L25267120”; 小華 . gender = “男”; 小華 . height = 182 ; 小美 . studentID = “L29627832”; 小美 . gender = “女”; 小美 . height = 163 ; ``` 重點: **有沒有覺得這樣很麻煩?現在還只是3個學生而已,要填的資料量也不多,如果物件和資料量多一點就會變成枯燥的打字任務,而且程式也會變得又臭又長,可讀性和維護性都會變差。** **那有沒有辦法在物件被建立出來的同時,就把這些資料輸入進去呢?也就是讓物件在被創造出來的同時,就一併完成「初始化」的動作。有的,就是本章要介紹的建構子(constructor)。** 我們加入建構子的觀念,將以上程式碼改寫如下: ```bash= public class Student { String studentID; String gender; int height; public Student(String studentID, String gender, int height) // 定義此類別的建構子 { this . studentID = studentID ; // 在建構子的{ }區塊中定義建構子要做些什麼事 this . gender = gender ; this . height = height ; System.out.println(“我的學號為” + studentID + “,” +“性別為”+ gender + “,” + “身高為”+ height +“公分”); } public int walk() { 此方法的實作程式碼 } public void say() { 此方法的實作程式碼 } } ``` 註:以上還用到了「this」變數,讀者可先不理會,待看完「this變數」章節之後就會懂了。 我們在這個類別中多寫了幾列程式碼,用來定義此類別的建構子。於是,我們就可以在從這個類別創造物件時,同時在建構子內輸入引數,這樣被創造出來的物件就會有初始值了,如下: ```bash= // 在創建object時,就創好初始值了 Student 小明 = new Student(“L25247845”,“男”,175); Student 阿華 = new Student(“L25267120”,”男”,182); Student 小美 = new Student(“L29627832”,”女”,163); ``` 並且這個建構子還包含一個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)的不同之處: 1. 定義建構子時不像函數一樣要先宣告回傳值的型態,建構子是「不可以」宣告回傳值型態的,即使寫void也不行。 2. JAVA強制規定該類別的建構子(constructor)的名稱,一定要和該類別(class)的名稱同名。 3. 建構子的權限一定要設為public。 因為以上三點差異,所以建構子和方法並不完全相同。話雖這麼說,但其實也不用特別去爭論建構子到底是不是一種特殊的方法,這只是認定的問題,我們學會怎麼用就好了。 ----------------------------------------------------------------------------------------- 建構子的(引數)多載: 我們知道方法(成員函數)可以多載(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(); } }
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.