Method(方法)

方法是為物件提供行為的函式,分為四大類:實例方法、運算子多載、Getter/Setter、抽象方法。

1. Instance methods 實例方法

  1. 隸屬類別實例物件的方法;
  2. 可直接存取實例變數,並使用 this 關鍵字;
  3. 具備完整函式主體,可用於商業計算、邏輯運作。
import 'dart:math';

class Point {
  final double x;
  final double y;

  // 建構子初始化實例變數
  Point(this.x, this.y);

  // 實例方法:計算兩點間距離
  double distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}

void main() {
  Point p1 = Point(0, 0);
  Point p2 = Point(3, 4);
  print(p1.distanceTo(p2)); // 輸出 5.0
}Code language: JavaScript (javascript)

2. Operators 運算子多載

  1. 多數運算子本質是具特殊命名的實例方法;
  2. 宣告語法:operator 運算子(參數) 回傳型別 { ... }
  3. 支援多載的運算子清單:
    < > <= >= == ~
    - + / ~/ * %
    | ˆ & << >>> >>
    []= []
  4. 內建運算子無法多載(例如 !=,由 Dart 底層自動實作,無須手動定義);
  5. 多載 == 時必須同步覆寫 hashCode,否則相等判斷會發生異常。
class Vector {
  final int x, y;

  Vector(this.x, this.y);

  // 多載 + 向量加法
  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
  // 多載 - 向量減法
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

  // 多載 == 相等判斷
  @override
  bool operator ==(Object other) =>
      other is Vector && x == other.x && y == other.y;

  // 配套覆寫 hashCode
  @override
  int get hashCode => Object.hash(x, y);
}

void main() {
  final v = Vector(2, 3);
  final w = Vector(2, 2);

  assert(v + w == Vector(4, 5));
  assert(v - w == Vector(0, 1));
  print(v + w);
}Code language: JavaScript (javascript)

透過多載函式,我們可以像數值一樣對兩個 Vector 物件執行 +、-、== 等原本只用於數字的運算。

3. Getters and setters 存取子

  1. get:唯讀方法,用於讀取計算屬性,無參數;
  2. set:寫入方法,修改關聯變數,僅有單一參數;
  3. 所有實例變數自帶隱式 getter,可變變數自帶隱式 setter;
  4. 優勢:後續可將一般變數改為計算邏輯,外部呼叫程式無需異動;
  5. 遞增/遞減 ++/-- 只會呼叫一次 getter,快取值避免副作用。
/// 螢幕座標矩形,原點(0,0)位於左上角
class Rectangle {
  double left, top, width, height;

  Rectangle(this.left, this.top, this.width, this.height);

  // Getter:計算右邊界
  double get right => left + width;

  // Setter:指定右邊界,反向更新 left
  set right(double value) => left = value - width;

  // Getter:計算下邊界
  double get bottom => top + height;

  // Setter:指定下邊界,反向更新 top
  set bottom(double value) => top = value - height;
}

void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);

  // 呼叫 setter
  rect.right = 12;
  assert(rect.left == -8);
  print(rect.left); // -8
}Code language: JavaScript (javascript)

4. Abstract methods 抽象方法

  1. 僅定義介面,無函式主體,以分號 ; 取代實作;
  2. 僅能存在於 abstract class 抽象類別 / mixin 混入類別;
  3. 子類別必須覆寫並實作全部抽象方法,否則子類別也需標記為 abstract
// 抽象類別,包含抽象方法
abstract class Doer {
  // 抽象方法:僅宣告,無實作
  void doSomething();
}

// 一般子類別,必須實作父類所有抽象方法
class EffectiveDoer extends Doer {
  @override
  void doSomething() {
    print("執行具體商業邏輯");
  }
}

void main() {
  Doer worker = EffectiveDoer();
  worker.doSomething(); // 輸出:執行具體商業邏輯
}Code language: JavaScript (javascript)

對照表

方法類型核心特徵語法標記適用場景
實例方法 Instance存取實例變數、完整邏輯主體一般函式定義物件常規行為(計算、商業操作)
運算子多載 Operator特殊命名實例方法,使用 operator 關鍵字operator +()自訂物件加減、索引、相等判斷
Getter/Setter讀寫屬性,get 無參、set 單參數get / set封裝計算屬性,對外統一讀寫入口
抽象方法 Abstract無函式主體,僅宣告介面方法後直接加 ;抽象父類定義規範,強制子類實作

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *