【初心者向け】FlutterサンプルコードのMyHomePage({Key key, this.title}) : super(key: key);って何?

こんにちは、図体デカ目です。

ある日、flutterを教えている方から記事タイトルのような質問がありました。

さて、これはコンストラクタのことです
コンストラクタとはクラスをインスタンス化する際に呼ばれるメソッドのことなのですが今回はフィールドを初期化するのに使っています。

ただ、このコンストラクタは少しわかりにくく書かれています。

他の言語(例えばJava)だと

MyHomePage(Key key,String title){
super(key);
this.title=title;
}

​こんな漢字で書かれ、呼び出しは

MyHomePage(null,"title名");
。

となりまが今回のタイトルのように、サンプルアプリのコンストラクタは「MyHomePage({Key key, this.title}) : super(key: key);」となっています。

これは一体、何をしているのでしょうか?

そこで、今回のコンストラクタでなにをしているか確認するための前提知識として以下の4つを紹介します。
①名前付きメソッド
②Named Constructors
③Redirecting Constructors
④Automatic field initialization


①について
Dartでは例えば以下のように関数やメソッドに名前付き引数を与えることが出来ます。

//メソッド定義
void hoge({String title, String subtitle}) {
}
//呼び出し方
hoge(title: 'hogeA', subtitle: 'subhogeB');

今回はコンストラクタの引数が名前付きになっています
また、指定しなかったらnullになります

②について
Dartは以下のように全く別物のコンストラクタを複数個設定することが出来ます

main() {
Hoge hoge = new Hoge.title('hogetitle');  //インスタンス生成時に呼びたいコンストラクタを決められる
print(hoge.title); // hogetitleと表示される
}
class Hoge {
String title;
Hoge() {
  this.title = 'foo';
}
Hoge.title(this.title);
}

上記の例では必ずfooとタイトル付けられてしまうコンストラクタと自由にタイトルを付けることが出来るコンストラクタを用意できました。
このようにインスタンスを生成する段階で、呼び出したいコンストラクタを自由に設定できます。


③について
Dartでは複数個コンストラクタが設定されている際に以下のように別のコンストラクタにリダイレクトすることが可能です

main() {
  Hoge hoge = new Hoge();     //Ⅰインスタンス生成
  print(hoge.title); // fooと表示される
}
class Hoge {
  String title;
  Hoge() : this.foo();    //コンストラクタ
  Hoge.foo() {
    this.title = 'foo';
  }
  Hoge.title(this.title);
}

Ⅰのインスタンス生成時にHoge側のコンストラクタを呼び出しています。
Hogeのコンストラクタでは【Hoge() : this.foo();】というようにコロンを用いてリダイレクト先のコンストラクタを設定しています。
つまりこのコードではHoge()というコンストラクタとHoge.foo()というコンストラクタが呼ばれているということです。

④について
Dartは以下の例のようにコンストラクタでthis.フィールド名と指定すれば代入処理を書かなくても自動で代入してくれます。

main() {
  Hoge hoge = new Hoge('foo');     //Ⅰインスタンス生成
  print(hoge.title); // fooと表示される
}

class Hoge {
  final String title;
  Hoge(this.title);
}

ここで、今回のサンプルアプリのコード(MyHomePage({Key key, this.title}) : super(key: key);)に戻りましょう。

・MyHomePage({Key key, this.title})
ここは名前付き引数でコンストラクタを設定しています
またAutomatic field initializationを利用しているのでtitleに入ってくる値は自動でフィールドに代入してくれます。
・: super(key: key);
これはMyHomePageのコンストラクタを呼び出す際のリダイレクト先を設定しています。
つまり、Redirecting Constructorsの利用です。
リダイレクト先はsuper(Key:key)となっているため、継承元のコンストラクタを設定(super()という呼び出しが継承元のコンストラクタを呼び出していること)しているということになります。
また、今回、呼び出し元はKeyを指定していないのでkeyにはnullが入っています。

ちなみにここのコードは冒頭で紹介していた以下のJavaのコードと全く同じ形でDartで書いても動きます。

いわば今回の疑問は数学でいうと途中式を省きまくってて何をしているかわからなくなっている状況です。
上記の4行のコードを一行にまとめるために①~④の知識が隠れていたということです。

この記事が気に入ったらサポートをしてみませんか?