👋
Dart NamedConstructorsを公式ドキュメントに基づいて調査する
前提
実務でNamedConstructorを見かけたが何をやっているかイマイチわからなかったので、公式ドキュメントに基づいて調査する。
個人的な目標は、種類の多いコンストラクタを理解しつつ、シングルトンパターンのコードを説明可能な状態にする。
最適な使い方や応用例は今後の実務コードやOSSのコードを読んで探ろうと思うので触れず、あくまで使い方と仕様にフォーカスする。
名前付きコンストラクタとは
Use a named constructor to implement multiple constructors for a class or to provide extra clarity:
名前付きコンストラクタを使用して、クラスに複数のコンストラクタを実装したり、明確さを高めたりします
サンプルコード
const double xOrigin = 30;
const double yOrigin = 70;
class PointWithNameConstructor {
final double x;
final double y;
PointWithNameConstructor(this.x, this.y);
// Named constructor
PointWithNameConstructor.origin()
: x = xOrigin,
y = yOrigin;
}
void main() {
final point = PointWithNameConstructor.origin();
print('${point.x},${point.y}');
}
出力結果
30,70
注意点
1. サブクラスが親クラスの名前付きコンストラクタを継承しない
こちらもドキュメント参照
A subclass doesn't inherit a superclass's named constructor. To create a subclass with a named constructor defined in the superclass, implement that constructor in the subclass.
サブクラス[1]はスーパークラス[2]の名前付きコンストラクターを継承しません。スーパークラスで定義された名前付きコンストラクターを持つサブクラスを作成するには、そのコンストラクターをサブクラスで実装します。
つまり以下のような使い方は出来ない。
const double xOrigin = 30;
const double yOrigin = 70;
class SuperPointWithNameConstructor {
final double x;
final double y;
SuperPointWithNameConstructor(this.x, this.y);
SuperPointWithNameConstructor.origin()
: x = xOrigin,
y = yOrigin;
}
class SubPointWithNameConstructor extends SuperPointWithNameConstructor {
SubPointWithNameConstructor();
}
void main() {
final point = SubPointWithNameConstructor.origin(); // originメソッドが存在しないと怒られる
print('${point.x},${point.y}');
}
2. 一部だけパラメータを変更したい場合
リダイレクトコンストラクタを使う。
まとめ
- 名前付きコンストラクタを用いることによって、クラスに複数のコンストラクタを実装できる。
OSSで名前付きコンストラクタを使用していた箇所
video_playerのVideoPlayerControllerの定義箇所
その他参考記事
Discussion