這是「計算機程式的思維邏輯」系列第 13 篇。前幾節我們探討了函式呼叫機制,接下來幾節將深入「類」的世界。本文將從自訂資料類型的角度,系統剖析 Java 類的四大構成要素、存取控制、建構子機制、記憶體生命週期,幫你建立完整的 OOP 思維框架。
程式本質是「資料 + 對資料的操作」。Java 提供 8 種基本型別,但真實世界的概念(如「訂單」、「使用者」、「幾何圖形」)遠超基本型別能表達的範圍。類就是讓我們自訂資料類型的機制,將屬性與操作封裝在一起,形成可複用、可擴充的模組。
Math、Arrays,僅靜態方法集合,不需實例化。| 分類 | 關鍵字 | 術語 | 說明 |
|---|---|---|---|
| 類型本身屬性 | static field | 類變數/靜態變數 | 如 Math.PI,屬於類,不屬於某個實例 |
| 類型本身操作 | static method | 類方法/靜態方法 | 如 Math.abs(),透過類名直接呼叫 |
| 實例擁有屬性 | instance field | 實例變數/成員變數 | 如 Point.x,每個物件獨擁一份 |
| 實例可執行操作 | instance method | 實例方法 | 如 Point.distance(),可直接存取實例變數 |
this,只能操作參數與靜態變數。this 參數,可直接存取實例變數。Math.PI)。this.x = x;this(0, 0); 必須放第一行。return this; 支援鏈式呼叫。Point 類class Point {
public int x;
public int y;
public double distance() {
return Math.sqrt(x*x + y*y);
}
}
使用:
Point p = new Point();
p.x = 2; p.y = 3;
System.out.println(p.distance()); // 3.605...
缺點:直接暴露欄位,無法驗證、攔截、記錄,違反封裝原則。
class Point {
private int x;
private int y;
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
public int getX() { return x; }
public int getY() { return y; }
public double distance() { return Math.sqrt(x*x + y*y); }
}
優點:可在 setter 加入驗證邏輯(如座標範圍檢查),未來易於維護擴充。
class Point {
private int x;
private int y;
public Point() { this(0, 0); } // 無參建構子,委派給下方
public Point(int x, int y) { this.x = x; this.y = y; } // 全參建構子
// getter/setter/distance 同前
}
使用:
Point p = new Point(2, 3); // 一行完成建立與賦值
建構子特性:
private → 單例模式、工廠模式、工具類防實例化new 或存取靜態成員時,類載入至方法區,靜態變數初始化,生命週期至 JVM 結束。new Point() 在堆配置記憶體,實例變數賦預設值,執行建構子,回傳參考存於棧區區域變數。this 參數,p.distance() 相當於 Point.distance(p)。| 關鍵字 | 可修飾對象 | 核心語意 |
|---|---|---|
| public | 類、方法、變數、建構子 | 公開存取 |
| private | 類、方法、變數、建構子 | 私有,僅類內可見 |
| static | 變數、方法、內部類 | 屬於類,非實例 |
| final | 變數、方法、類 | 不可變/不可覆寫/不可繼承 |
| this | (非修飾符) | 當前實例參考 |
本節的 Point 類屬性皆為基本型別。下一節將探討類的組合——當屬性本身也是物件時,如何表達更複雜的領域模型(如「訂單包含多個訂單項」、「學生屬於某個班級」)。敬請關注微信公眾號「老馬說程式」獲取最新內容。