Method(メソッド)

メソッドとはオブジェクトに振る舞いを与える関数のことで、大きく4種類に分類されます:インスタンスメソッド、演算子オーバーロード、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);

  // インスタンスメソッド:2点間の距離を計算
  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)

演算子をオーバーロードすることで、数値と同じように2つのVectorオブジェクトに対し +、-、== といった数値向け演算子を使用できるようになります。

3. Getters and setters アクセサ

  1. get:読み取り専用メソッド、計算プロパティを取得、引数なし;
  2. set:書き込みメソッド、関連変数を更新、引数は1つのみ;
  3. 全てのインスタンス変数に暗黙的getterが付属、可変変数には暗黙的setterも付属;
  4. メリット:後から通常変数を計算ロジックに切り替えても外部呼び出しコードの修正が不要;
  5. インクリメント/デクリメント ++/-- はgetterを1回だけ呼び出し、値をキャッシュして副作用を回避する。
/// 画面座標系の矩形、原点(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は引数1つget / set計算プロパティをカプセル化、外部統一アクセス窓口
抽象メソッド Abstractメソッド本体なし、インターフェース宣言のみメソッド末尾に ;抽象親クラスで仕様定義、サブクラスに実装を強制

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です