【 Flutter 】Flutter を 基礎 から 学習 ( Dart編 ) part21 コンストラクタ

基礎 から 学ぶ Flutter 」という書籍で  学習 したことを ブログでアウトプットしていこうと思います。今回は Dart編 ( part21 )です。

前回

【 Flutter 】Flutter を 基礎 から 学習 ( Dart編 ) part20 コンストラクタ

今回もコンストラクタの学習です。

クラス

initializer list

Dartでは以下の順序でコンストラクタが実行されます。

  1. 継承元
  2. 自分自身

継承元のコンストラクタ実行前に何らかの処理を行いたい場合はinitializer listという機能を使用できます。
Javaではインスタンスイニシャライザと呼ばれている機能ですね。
この機能を使用すると、継承元のコンストラクタが実行される前に実行が可能となります。

コンストラクタが複数存在する場合に共通処理として使用するとよさそうです。
コンストラクタが無い(匿名クラス・無名クラス)で疑似的にコンストラクタ処理を実現できます。

Dartのinitializer listは、自身のコンストラクタの引数リストの後ろにコロン:を記述して定義します。

class Hoge {
  String name = '';
  // Dartではメソッドのオーバーロードを認めていません。
  // よって、同盟のコンストラクタは1つだけです。
  // 場合によってコンストラクタの呼び出しを使い分けたい場合は
  // named constractorsを使用するようです。
  //Hoge() {
  //  print('継承元 :引数無し');
  //}
  
  Hoge(String value) {
    print('継承元 :引数あり・・・$value');
  }
}

// このクラスはHogeを継承し、initializer listでコンストラクタより前に別の処理を行おうとしています。
// 継承元のクラスに「引数無し」コンストラクタが存在する場合は問題ないのですが、今回の場合はinitializer listに
// 「絶対に(?)」明示的に継承元のコンストラクタを実装する必要があるようです。
//class Fuga extends Hoge {
// num age = 0;
//  Fuga(String value)  : 
//  age  = 20 // ←これがinitializer list
//  {
//    print(age);
//  }
//}

class Haga extends Hoge {
  num age = 0;
  Haga(String value)  : 
  age  = 20, // カンマで区切り複数の文(式?)を定義できます。
  // print('コンストラクタ'), フィールドの初期化にしか使えないようでした。(printがコンパイルエラー)
  super(value)    // 今回はコンストラクタを呼び出しました。
  {
    print(age);
  }
}


void main() {
  var a = Haga('太郎'); 
}

どういうこと?

以下の認識でよいのですかね?

継承元が「引数無し」のコンストラクタを持っている場合 → 継承先のコンストラクタでは自動的呼び出す

継承元が「引数あり(named constractorsではない」のコンストラクタを持っている場合 → initializer listで継承元のコンストラクタを明示的に呼び出す必要がある

最後に

initializer listでは以下のことができるという認識です。

  • フィールドの初期化と
  • 引数ありの継承元コンストラクタ呼び出しを行う

継承元で引数ありのコンストラクタが定義されている場合は必ずinitializer listを使うようです。

今回衝撃だったのはDartでは「オーバーロードを許していない」という点です。
理由はあると思うのですが今まで当たり前のように使用してきたのでちょっと不安になりました(´・ω・`)

今日はここまで!