Java – 物件導向 – 建構式 Constructor

通常, 在運用類別產生物件實體的時候, 會以 new 加上該類別所提供的建構式來指派給一個物件變數. 而建構式對於一個物件實體而言, 只會在該物件實體進行初始化的時候被呼叫執行一次, 之後就與建構式一點關係都沒有了. 換言之, 只會被執行一次.

Bike urBike = new Bike();
  • new 就是用來在記憶體中產生一個物件實體.
  • Bike() 為 Bike 類別中的建構式, 用來將剛剛 new 所產生的物件實體, 進行初始化的處理程序.

切記, 所有的類別, 都一定有建構式(Constructor).

可是, 前面單元所設計的Bike類別, 就沒有撰寫建構式的程式, 何以說: 所有的類別, 都一定有建構式? 因為,

類別中, 沒有定義任何的建構式, 將會在編譯時期, 以父類別(super class)的沒有傳遞任何參數的建構式, 為其唯一的建構式.

可是, 前面單元所設計的Bike類別,

// 腳踏車的設計圖
public class Bike {
  private double speed;	// 速度
  
  // 加速功能
  void upSpeed() {
    if (speed < 1) {
      speed = 1;
    }else {
      speed *= 1.2;
    }
  }
  
  // 煞車功能
  void downSpeed() {
    if (speed < 1) {
      speed = 0;
    }else {
      speed *= 0.7;
    }
  }
  
  // 加裝速度表
  double getSpeed() {
    return speed;
  }
}

也沒有定義父類別, 何來的父類別? 因為,

定義類別時, 沒有指定父類別, 將會以 java.lang.Object 為其父類別.

// 腳踏車的設計圖 : extends Object 預設繼承 java.lang.Object
public class Bike extends Object {
  private double speed;	// 速度
  
  // 加速功能
  void upSpeed() {
    if (speed < 1) {
      speed = 1;
    }else {
      speed *= 1.2;
    }
  }
  
  // 煞車功能
  void downSpeed() {
    if (speed < 1) {
      speed = 0;
    }else {
      speed *= 0.7;
    }
  }
  
  // 加裝速度表
  double getSpeed() {
    return speed;
  }
}

 

所以, 所有類別, 除了 java.lang.Object 之外, 都會有一個父類別, 不會沒有.

以上的內容, 似乎寫了一堆規則, 事實上, 還是只有一般的觀念而已. 每個人, 都只有一個親生父親, 單一繼承. 但是追朔到源頭, 就是只有一個最源頭的父親是沒有爸爸的, 就當作是迸出美猴王的那顆石頭好了. 之後的所有人, 都一定會有一個父親.

再來, 所有的類別都有可能產生物件實體, 而物件實體除了利用 new 關鍵字所產生最陽春的物件實體之後, 都會經過初始化的程序, 也就是建構式在定義的內容, 是必經的程序. 因此, 就算是類別中沒有定義, 也將會以父類別中的沒有傳遞參數的建構式, 為其唯一的建構式; 如果有自己類別定義的任何建構式, 就不存在父類別中的沒有傳遞參數的建構式. 反正, 就是會有建構式就對了.

 

建構式的寫法


  • 與一般方法定義方式一樣
  • 唯獨沒有定義傳回值型別, 所以也不會有 return 敘述句.
  • 方法名稱與類別名稱大小寫完全一樣
  • 與方法一樣可以有多個名稱一樣, 但是參數個數, 型別不同的不同建構式

先來看看Bike類別的父類別 java.lang.Object

的確在Constructors(建構式)中存在了一個Object()的沒有傳遞任何參數的建構式.

 

實證過程


所以, 回到Bike的類別來看, 因為沒有定義任何的建構式, 就會在編譯時期, 以java.lang.Object的 Object() 為其唯一的建構式, 也才進一步的使用了 new Bike() 來產生一個 Bike 的物件實體.

接著, 來重新定義Bike自己的建構式

// 腳踏車的設計圖
public class Bike extends Object {
  private double speed;	// 速度
  // 定義建構式
  Bike(){
    System.out.println("Bike()");
  }
  
  // 加速功能
  void upSpeed() {
    if (speed < 1) {
      speed = 1;
    }else {
      speed *= 1.2;
    }
  }
  
  // 煞車功能
  void downSpeed() {
    if (speed < 1) {
      speed = 0;
    }else {
      speed *= 0.7;
    }
  }
  
  // 加裝速度表
  double getSpeed() {
    return speed;
  }
}

此時, 如果再來練習建構出一個Bike物件實體:

public class PlayBikeV3 {

  public static void main(String[] args) {
    Bike bike1 = new Bike();
  }

}

將會發現執行結果會出現

Bike()

因為, 以自己定義的建構式來進行初始化的程序.

一個類別中, 可以提供多種不同參數型別及個數的建構式. 例如:

// 腳踏車的設計圖
public class Bike extends Object {
  private double speed;	// 速度
  // 定義建構式
  Bike(){
    System.out.println("Bike()");
  }
  Bike(double speed){
    this.speed = speed;
    System.out.println("Bike(double)");
  }
  
  // 加速功能
  void upSpeed() {
    if (speed < 1) {
      speed = 1;
    }else {
      speed *= 1.2;
    }
  }
  
  // 煞車功能
  void downSpeed() {
    if (speed < 1) {
      speed = 0;
    }else {
      speed *= 0.7;
    }
  }
  
  // 加裝速度表
  double getSpeed() {
    return speed;
  }
}

 

 

%d bloggers like this: