いろんな説明を読んでもいまいちピンとこないFlutterの
「コンストラクタ({super.key});」の部分について調べてみた。
class Xxx extends StatelessWidget {
Xxx({super.key}); //ここな
@override
Widget build(BuildContext context) {
return Container();
}
}
「super」というキーワード自体は、親クラスのコンストラクタやメソッドを呼び出すために使用されるが、「super.key」の文脈での使用は、親クラスのコンストラクタに引数を渡す特定の目的に限定される。
super.keyはスーパークラス(StatelessWidget)のコンストラクタにキーを渡しており、これによりウィジェットが適切に初期化される。
順番としては、
①別のクラスからXxxクラスのウィジェットを生成
②Xxxクラスでは渡されたパラメータをsuper.keyという書き方でスーパークラスに渡す
③スーパークラス(StatelessWidget)は、この渡されたキーを受け取り、ウィジェットの識別子として内部的に保持する。
Javaの感覚で「super.keyはスーパークラスで保持しているkeyという値を参照」と考えてしまいそうだが、これが大きな誤解を招く。
Javaのサンプル
public class MathUtility {
public static final double PI = 3.14159;
public static int add(int a, int b) {
return a + b;
}
}
// どこか他のクラスから
double piValue = MathUtility.PI;
int result = MathUtility.add(5, 3);
この例では、MathUtilityクラスに静的な変数PIと静的なメソッドaddが定義されています。外部のクラスからこれらの静的メンバーには、クラス名を使って直接アクセスする。
Flutterでウィジェットを作成する際、ほとんどのウィジェットコンストラクタにはkeyという名前付きパラメータが用意されている。
これにより、開発者はウィジェットに任意のキーを指定して、そのウィジェットの一意性や状態の管理を容易にすることが可能となる。
Dartにおいても、同様の概念が存在する。
クラスの静的メンバーは、インスタンス化せずにクラス名を通じてアクセスすることができる。
class Constants {
static const double pi = 3.14159;
}
// アクセスする
double myPi = Constants.pi;
Flutterにおいて、ウィジェットのコンストラクタにkeyパラメータを渡す場合、このキーはインスタンスのプロパティとして扱われ、ウィジェット固有の識別に使用される。
これは静的アクセスとは異なり、特定のウィジェットのインスタンスに属するものになる。
var myWidget = Xxx(key: Key('unique_key'));
super.keyはスーパークラスのkey値をコンストラクタに渡す、というように見えるけど、keyというパラメーターに値がkey: xxxのような形式で渡された場合はスーパークラスのコンストラクタにkeyで指定された値を渡す、という意味になる。
super.keyという記載方法ができるようになったのはDart 2.12のリリースから。
それ以前では下記のような記載だった。
class Xxx extends StatelessWidget {
Xxx({Key? key}) : super(key: key); // key をスーパークラスのコンストラクタに渡す
@override
Widget build(BuildContext context) {
return Container();
}
}
Dart 2.12から「Xxx({super.key});」となり、書きやすくなった。
「Xxx({Key? key}) : super(key: key);」の記法は現在でも有効だが、Dart 2.12以降ではsuper.keyのようにパラメータの転送をより簡潔に行えるようになったため、コードをシンプルに保つことができる。