Dartのコンストラクタの書き方まとめた

## 普通のクラス

```dart
class Sample { 
  void doSome() {}
}

void main() {
  final sample = Sample();
  sample.doSome();
}
```

## コンストラクタ引数を持つクラス

```dart
class Sample {
  Sample(this.name);

  final name;

  void doSome() {}
}

void main() {
  final sample = Sample("hoge");
  sample.doSome();
  print(sample.name);
}
```

## constをつけたコンストラクタ引数を持つクラス

```dart
class Sample {
  const Sample(this.name);

  final name;

  void doSome() {}
}

void main() {
  final sample = const Sample("hoge");
  sample.doSome();
  print(sample.name);
}
```

## コンストラクタ引数に名前つけて渡してインスタンス化させたい

```dart
class Sample {
  const Sample({this.name});

  final name;

  void doSome() {}
}

void main() {
  final sample = const Sample(name: "hoge");
  sample.doSome();
  print(sample.name);
}
```

## クラスのプロパティに型を付けたい

```dart
class Sample {
  const Sample({required this.name});

  final String name; // nullableにしてコンストラクタのrequiredを外すこともできる

  void doSome() {}
}

void main() {
  final sample = const Sample(name: "hoge");
  sample.doSome();
  print(sample.name);
}
```

## クラスのプロパティのfinal消すとクラスをconstにできない

```dart
class Sample {
  Sample({required this.name});

  String name; // finalじゃないのでconstでインスタンス化できない

  void doSome() {}
}

void main() {
  final sample = Sample(name: "hoge");
  sample.doSome();
  print(sample.name);
}
```

## こういうコンストラクタの書き方もあるよ

```dart
class Sample {
  Sample(String name) {
    this.name = name;
  }

  String? name;

  void doSome() {}
}
```

## コンストラクタ引数の処理の書き方

Initializer listと呼ばれる書き方
ちょっと冗長

```dart
class Sample {
  const Sample({
    String name,
  }) : _name = name;  

  final String? _name;

  void doSome() {}
}
```

前半で紹介した書き方にするとすっきり

```dart
class Sample {
  const Sample({this.name});

  final String? name;

  void doSome() {}
}
```

## 複数コンストラクタ引数ある場合片方だけ名前つけて渡せるようにもできる

```dart
class Sample {
  const Sample(this.name, {required this.age});

  final String name;
  final int age;
  
  void doSome() {}
}

void main() {
  final sample = Sample("", age: 99);
  print(sample.name);
  print(sample.age);
  sample.doSome();
}
```

## 名前付きコンストラクタ

```dart
class Sample {
  const Sample({required this.name, required this.age, this.gender});
  const Sample.man({required this.name, required this.age, this.gender = "man"});
  const Sample.woman({required this.name, required this.age, this.gender = "woman"});

  final String name;
  final int age;
  final String? gender;
  
  void doSome() {}
}

void main() {
  final sample = const Sample(name: "hoge", age: 9);
  print(sample.name);
  print(sample.age);
  sample.doSome();
  
  final sampleMan = const Sample.man(name: "hoge", age: 2);
  final sampleWoman = const Sample.woman(name: "hoge", age: 5);
  
  sampleMan.doSome();
  sampleWoman.doSome();
}

```

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

全部リダイレクト側でコンストラクタ引数処理する

```dart
class Sample {
  const Sample({required this.name, required this.age, this.gender});
  const Sample.init() : this(name: "", age: 0, gender: "");

  final String name;
  final int age;
  final String? gender;
  
  void doSome() {}
}

void main() {
  final sample = const Sample.init();
  print(sample.name);
  print(sample.age);
  sample.doSome();
}

```

引数の値を渡してリダイレクト

```dart
class Sample {
  const Sample({required this.name, required this.age, this.gender});
  const Sample.init(name, age) : this(name: name, age: age, gender: "");

  final String name;
  final int age;
  final String? gender;
  
  void doSome() {}
}

void main() {
  final sample = const Sample.init("", 90);
  print(sample.name);
  print(sample.age);
  sample.doSome();  
}

```

コンストラクタ引数に名前もつけられる

```dart
class Sample {
  const Sample({required this.name, required this.age, this.gender});
  const Sample.init({name, age}) : this(name: name, age: age, gender: "");

  final String name;
  final int age;
  final String? gender;
  
  void doSome() {}
}

void main() {
  final sample = const Sample.init(name: "", age: 90);
  print(sample.name);
  print(sample.age);
  sample.doSome();  
}
```