# 初始化物件 Constructor

> 決定好類別的屬性及方法了，但我想在創造物件的同時對我的物件進行設定

## 建構子，Constructor，又稱建構者涵式，

在工程師使用 new 關鍵字來創造物件時被呼叫，用來初始化物件的資料欄位。

![](https://1201963393-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLRnhT9aTkN9HvaBP28%2Fsync%2Fc1706017efc99a9d4c5e1e95059f1f1bce96141b.jpg?generation=1604653628508093\&alt=media)

## 建構子的定義：

```java
class Test{
  Test([arguments]){
    // do someing
  }
}
```

## 建構子有幾個特點：

1. 必須與類別名稱同名。
2. 不可以有回傳值。
3. 可以帶入引數(arguments)。
4. 主要功能為初始化物件，搭配new關鍵字被呼叫。
5. 可以有多個建構子，但引數型態個數不可以相同。

來看看前一章節定義的類別：

```java
class Human{
  String name;
  int age;
  int height;
  void eat(){
    System.out.println("eating");
  }
  void sleep(){
    System.out.println("Zzz");
  }
}//end of class Human
```

發現到！！我們根本沒有定義建構子阿阿阿，太扯了這樣還能動的話我幹嘛要知道建構子是什麼？

先別急，如果沒有定義建構子的話，

```java
Human h1 = new Human();
```

new 後面的那個 Human() 到底又是什麼!?!?

原來Java知道有時候工程師只想設計類別，不需要利用到建構子去初始化欄位，因此只要你的類別中『沒有定義建構子』，那就會幫你定義一個『不帶參數』的建構子，而且這個建構子『沒有做任何事』，你連看都看不到XD

以程式碼來看的話，Human這個class，看起來就像這樣：

```java
class Human{
  String name;
  int age;
  int height;
  /*
  Human(){    //不帶參數，且不作任何事，Java幫你加上去的，你看不到，也不存在程式碼中
  }
  */
  void eat(){
    System.out.println("eating");
  }
  void sleep(){
    System.out.println("Zzz");
  }
}//end of class Human
```

因為Java有這麼貼心的設計，所以

```java
Human h1 = new Human();
```

才能順利動作，而不會錯誤。

## 設計建構子

現在我們知道Java會很sweet的幫我們加上不帶參數不作任何事的建構子，但我就是需要建構子來幫我初始化物件阿！ 好，那先想想，我們需要建構子幫我們幹嘛？

以上面定義的Human類別為例，假設我希望在創造物件的時候，順便幫我把物件的name這個欄位設定好，那我可以這樣寫我的建構子。

```java
Human(String str){
  name=str;
}
```

這樣我在創造物件的時候，就可以搭配new關鍵字在呼叫這個建構子，來達到我希望的結果。

```java
class Test{
  public static void main(String[] args){
      Human h1 = new Human("小木");  // 這行 OK
      Human h2 = new Human();        // 這行編譯錯誤
  }
}
```

在定義 h1 物件的時候，我們搭配了『代有一個字串參數的建構子』來初始化我們的物件，但為什麼在初始化 h2 物件的時候會出錯呢？ 明明在剛剛都是那樣寫的！！

嗯 要特別注意的是，Java只會在你『沒有任何建構子』的時候，幫你加上一個不帶參數的建構子，如果你自己有定義了建構子，那就不會幫你定義一個不帶參數的建構子。

如果你希望還是要有一個不帶參數的建構子的話，那很簡單，自己定義就行了：

```java
class Human{
  String name;
  int age;
  int height;
  Human(){  // Java不會自動幫你加，如果你有需要可以自己寫
  }
  Human(String str){  // 接收一個字串參數來設定name
    name=str;
  }
  Human(String str,int a,int b){ //當然也可以這樣一次設定完
    name=str;
    age=a;
    height=b;
  }
  void eat(){
    System.out.println("eating");
  }
  void sleep(){
    System.out.println("Zzz");
  }
}//end of class Human
```

這個時候要定義物件就可以透過建構子很輕鬆的設定。

```java
class Test{

  public static void main(String[] args){
    Human h1 = new Human();
    Human h2 = new Human("小婷");
    Human h3 = new Human("小木",22,178);
  }// end of main(String[])

}// end of class Test
```
