🐻‍❄️

Dart のコンストラクタの基本 (できることまとめ)

2021/11/13に公開

通常のコンストラクタ

Dart ではコンストラクタに引数を渡してプロパティを初期化できる。しかし以下のように this.[プロパティ名] と記述する必要があったり、プロパティの宣言時に初期値をセットする必要があるなど、使い勝手がかなり悪い。

class Dog {
  String name = "";
  Dog(String name) {
    this.name = name;
  }
}

void main(List<String> arguments) {
  var dog = Dog("Pochi");
  print("dog name is ${dog.name}");
}
dog name is Pochi

上記の方法だと使い勝手が悪いこともあり、 Dart ではプロパティ名をそのままコンストラクタの引数に指定することでプロパティの初期化ができるという Sugar Syntax が用意されている。以下の方法だと this.[プロパティ名] を記述する必要もないし、プロパティの宣言時に初期値をセットする必要もなくかなりスッキリ書くことができる。

class Cat {
  String name;
  Cat(this.name);
}

void main(List<String> arguments) {
  var cat = Cat("Mike");
  print("cat name is ${cat.name}");
}
cat name is Mike

上記のコンストラクタ定義だとインスタンス生成時に引数名を省略した形になる。もしインスタンスを生成するときに引数名を省略したくない場合には名前付き引数を利用する。

class Tiger {
  String name;

  Tiger({required this.name});
}

void main(List<String> arguments) {
  var tiger = Tiger(name: "leo");
  print("tiger name is ${tiger.name}");
}
tiger name is leo

名前付きコンストラクタ

Dart では名前付きコンストラクタを定義できる。名前付きコンストラクタを利用すればインスタンスを用途ごとに分けて生成しやすくできる。

class Bird {
  String name;
  Bird(this.name);
  Bird.unknown(): name = "UNKNOWN";
}

void main(List<String> arguments) {
  var bird = Bird.unknown();
  print("bird name is ${bird.name}");
}
bird name is UNKNOWN

リダイレクトコンストラクタ

Dart ではリダイレクトコンストラクタを定義できる。リダイレクトコンストラクタを利用するとあらかじめ定義してあるコンストラクタを利用してインスタンスを生成できる。

class Bear {
  String name;
  Bear(): this.name("UNKNOWN");
  Bear.name(this.name);
}

void main(List<String> arguments) {
  var bear1 = Bear();
  print("bear name is ${bear1.name}");
  var bear2 = Bear.name("Kuma");
  print("bear name is ${bear2.name}");
}
bear name is UNKNOWN
bear name is Kuma

ファクトリーコンストラクタ

Dart ではファクトリーコンストラクタを定義できる。ファクトリーコンストラクタを利用すると常に新しいインスタンスを生成したくない場合に予め生成しておいたインスタンスを返すような実装ができる。

class Logger {
  static Logger? _logger;

  factory Logger() {
    _logger ??= Logger._internal();
    return _logger!;
  }

  /// Logger インスタンスを生成するためのコンストラクタ(内部呼び出し用)
  Logger._internal();

  void log(String message) {
    print(message);
  }
}

void main(List<String> arguments) {
  var logger1 = Logger();
  var logger2 = Logger();
  var isSame = logger1 == logger2;
  print("logger is ${isSame ? "same" : "different"}");
}
logger is same

参考文献

A tour of the Dart language

Discussion