🙄

Flutter コンストラクタを理解するために

2021/09/09に公開

Flutter コンストラクタを理解しないと読めないStatefulWidget

StatefulWidgetを理解するためのコンストラクタ解説

本稿、あるいは本シリーズはFlutter公式ドキュメントを参考に理解を深めていくプログラミングノートである

■StatefulWidgetでハマった理由

FlutterのStatefulWidgetを理解してコードを書くには、コンストラクタなどの前提知識が必要なのだが、そうした知識が不足しているためハマった。

以下のコードはFlutterのNewProject生成時のデフォルトコードである(一部抜粋したもの)。いつものクリックすると何回クリックしたかカウントするアプリ。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
  
  Widget build(BuildContext context) {
  
  以下略

問題は MyHomePageクラス の

MyHomePage({Key? key, required this.title}) : super(key: key);

という部分なのだが、Key? keyってなに(superもわけ分からんがまずはコンストラクタから解決する)。

Flutterエンジニアの方々が公開した記事にも初歩的な解説はあったものの、ディグってる時に発見したJavaのコンストラクタの解説記事が概要を学ぶためには効果的だった(あと、Dartのドキュメントも読んだ)。

コンストラクタとは、一言で言うとインスタンス生成時に実行されるメソッドのことを指します。

インスタンスとは、いわば設計図を元にして作った実物のようなものであり、「new クラス名」とすることで生成することができます。

コンストラクタは、主にクラス内で使われる変数を初期化するために使われます。普通のメソッドと同じように、コンストラクタも引数を指定して実行することが可能です。
つまり、コンストラクタに対して何か情報を与え、その情報を元にクラス内で使われる変数を初期化できるということです。

このように、インスタンス生成時に実行されるメソッドがコンストラクタです。

Tech Teacher Blog 【初心者向け】Javaのコンストラクタについて解説!サンプルコードも紹介! https://www.tech-teacher.jp/blog/java-constructor/#:~:text=コンストラクタは、主にクラス,化できるということです。 2021/09/08に引用

本稿のデフォルトコードでいうと、コンストラクタに「key」と「title」を渡している。そして、 MyApp(StatelessWidget)の中で「home: MyHomePage(title: 'Flutter Demo Home Page')」といった具合に呼ばれている。そのため、MyHomePageで初期化してあげないとtitleがMyAppで使えませんね。そのため、初期化のためにコンストラクタで渡してあげているというわけだったんですね。

しかし、一つ疑問が残ります。「Key? key」とは何でしょうか。

MyApp の stateless ウィジェットで title を渡していますが、key はデフォルトでユニークなものが渡されます。

そのあとに : super(key: key) と書かれています。
Redirecting constructors と呼ばれる手法で、別のコンストラクタの処理を追加で行なっています。親クラスにもキーを渡しているんですね。

@naoaki_kaito Flutter未経験者に初期サンプルコードの説明をしてみた https://qiita.com/naoaki_kaito/items/ed77ee085ad61f951784 2021/09/08
い引用

どうやら、superでもkeyをしており、ここではスーパークラスにKeyを渡しているようだ。この辺りをきちんと理解するにはsuper、またはスーパークラスについての理解が必要であるため、別稿では学んでみる。

いずれにせよ、本稿で紹介しているFlutterのデフォルトコードではkeyを指定されていないので、nullになる。

ちなみに、ここではMyAppで、titleが指定されているが、その変数名をtestTitleにするとどうなるだろうか。もちろんエラーを吐く。コンストラクタもtestTitleにし、testTitleも初期化すると該当箇所のエラーは解決される(該当箇所は、であるが)。

それにしても、初期コードを読むだけでかなりの情報量が必要だ。とりあえず、本稿ではコンストラクタにも引数を渡せるということを学んだ。その具体的な使い方は今後、分かっていくだろう。いずれにせよ、スーパークラスについても理解しないと、本稿で取り上げた初期コードは理解できそうにない。

以上

Discussion