基礎程式設計(Java)· CH8

類別與物件深入

this · 多載建構子 · 組合 · static · final · enum · 導覽地圖

完整內容看 PDF 講義,互動對照與試跑看 index。

全章主線

static vs instance:最關鍵的分界

static(類別層級)
整個類別共享一份
用類名呼叫、無 this
例:物件計數、PI、main
instance(物件層級)
每個物件各一份
用物件呼叫
例:name、balance

「共享一份」還是「各一份」決定了大半考點。

自我參照

this:指向目前這個物件

public void setHour(int hour) {
    this.hour = hour;   // 左邊實例變數,右邊參數(區分同名)
}

沒遮蔽時可省略;也可 this(...) 在建構子第一行呼叫另一建構子。

建立方式

多載建構子

public Time() { this(0, 0, 0); }          // 無引數
public Time(int h) { this(h, 0, 0); }     // 一參數
public Time(int h, int m, int s) { ... }  // 三參數

參數列不同即可多載。一旦自寫建構子,預設無引數建構子就消失,要自己補。

has-a

組合:類別內含另一物件

public class Employee {
    private Date birthDate;     // 欄位是另一個物件
}
emp.getBirthDate().getYear();   // 層層點號

組合是 has-a(A 有一個 B),不是繼承(is-a)。內含物件忘了 new → NullPointerException

類別成員

static:所有物件共享一份

private static int count = 0;   // 類別變數,共享
public Employee() { count++; }  // 每 new 一個 +1
Employee.getCount();            // 類名.方法()

static 方法不能用 this、不能直接存取實例變數(執行時可能還沒物件)。

常數

final:只能賦值一次

private final double radius;            // 物件常數(建構子設一次)
public static final double PI = 3.14159; // 類別常數(全大寫慣例)

final 漏賦值或想二次賦值都會編譯錯。

列舉

enum:一組固定具名常數

public enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
for (Day d : Day.values())
    System.out.println(d + " " + d.ordinal());  // 0 起

values() 全部常數、ordinal() 序號(0 起)、valueOf("MON") 字串轉常數。

精確金額

BigDecimal:別用 double 算錢

0.1 + 0.2            // double → 0.30000000000000004(誤差)
new BigDecimal("0.1").add(new BigDecimal("0.2"))  // → 0.3(精確)
price.multiply(qty)                  // 用方法,不能寫 price * qty
total.setScale(2, RoundingMode.HALF_UP);  // 兩位、四捨五入

double 是二進位浮點、算十進位金額有誤差。BigDecimal字串建構才精確,運算用 addmultiply 方法(不是 + *)。

其餘

static import · 套件 · GC

  • import static java.lang.Math.*; → 直接寫 sqrtPI
  • 存取層級:public → package-private(無修飾子)→ private
  • 垃圾回收自動收無參照物件;finalize 已過時,不依賴它

接下來

把 static 與組合練到自動

  • PDF 講義 完整內容+static/組合藍圖圖
  • index static vs instance 對照+試跑+組合步進
  • 本地練習 6 題 多載/static/組合/enum/final/BigDecimal
  • 複習測驗 自測到 90%