Flutterを普段使ってよく見かける super について普段は「お作法だな」ぐらいの理解しかなかったのでせっかくならsuperとはどういうもので、どんな旨味や利点があるのかを調べてまとめてみました。
Widget生成時によく見るsuper.keyとは何なのかやsuperを使ってどんなことができるかを知りたい、深掘りたい方の参考になれば幸いです。
superとは
まずsuperとは
- 「親クラスの機能を呼び出すためのキーワード」
です。
Flutterでよく見かけるのは、下記のような形。
class MyWidget extends StatelessWidget {
MyWidget({super.key});今回は2パターンについてソースコードとともに解説していきます。
- super.keyは何をしている
- superで親クラスのメソッドを呼ぶ
super.keyは何をしている
サンプルコード
class MyWidget extends StatelessWidget {
MyWidget({super.key}); // super.key は「super(key: key)」の省略形
@override
Widget build(BuildContext context) {
return const Text('Hello');
}
}
このクラスの状況としては、以下の通りです。
StatelessWidgetを継承しているMyWidgetMyWidgetのコンストラクタでsuper.keyを宣言している
Flutterの仕組み
上記サンプルコードの解説の前に、そもそものFlutterの仕組みとして以下のような点があります。
- Flutterでは、KeyはWidgetツリー管理に使われる
- 実際にKeyを管理するのは上位のクラス(Widget / Element)
- 子クラスはKeyを自分で持たない
- Keyを親に渡す
- Flutterの標準Widgetはkeyを受け取れるようにするのが標準の書き方
const Widget({Key? key});- null 許容のKey 型(Key?)なので値を渡しても(何も渡さなくても)OK
superの理解
上記のFlutterの仕組みから、子クラスはkeyを自分で持たず親に渡しています。
子(MyWidget)が親(StatelessWidget)に「keyを渡してね」の宣言が以下の部分です。
MyWidget({super.key});これは、Dart 2.17 以降の省略形の形で、理解するために本来は以下のような形になるのを省略しています。
MyWidget({Key? key}) : super(key: key);やっていることとしては
- 自分で受け取ったKeyを親に渡している
- ここがKey?だから呼び出し側は別にkeyを必須で引数に定義しなくて空でも良い
- むしろ基本keyは書かないことの方が多い
です。
それを省略して
MyWidget({super.key});となります。
これで何気なく普段生成されているsuper.keyが親クラスに子クラスがkeyを渡しているんだなと理解できるかなと思います。
superで親クラスのメソッドを呼ぶ
もうひとパターン見てよりsuperを理解したいと思います。
class Animal {
void speak() {
print("Animal sound");
}
}
class Dog extends Animal {
@override
void speak() {
super.speak(); // 親クラスの speak() も実行
print("Woof!");
}
}出力結果は、以下の通り。
Animal sound
Woof!このクラスの状況としては以下の通りです。
- DogクラスがAnimalクラスを継承
- オーバライドしAnimalクラスでspeakメソッドを定義
superを使う理由
superを使う理由としては、以下の通りです。
- 親クラスのメソッドの動きを残しつつ、子クラスの動きを追加したい場合に有効
- オーバライドするが、
super.を使えば親クラスのオリジナルの関数を呼び出せる
- オーバライドするが、
上記のサンプルの場合だと、
- Dogは「犬として吠える」が「動物の基本の鳴き方」も実行したい場合
に有効になります。
オーバライドについて深く知りたい方は下記の記事がわかりやすかったのでおすすめです。

Flutterでも使われる例
Flutterの標準でもこの仕組みが使われています。
例:State クラスの initState
@override
void initState() {
super.initState(); // 親 State の初期化も必ず行う
// 子クラスの初期化処理
}ここで super.initState() を忘れると親クラスの初期化が行われず、動作に問題を起こすため.superが必要になります。
つまり、
- superを使って親クラスのメソッドを呼ぶことで、子クラスでオーバライドした新しい処理と親クラスの元の処理の両方が実行が可能
になります。
これで2つ目の「superで親クラスのメソッドを呼ぶ」についても親クラスや子クラスで柔軟にメソッドを使い分けたい時に有効に使えることが理解できたかなと思います。
最後に
簡単ではありますが、superについて解説していきました。理解を深めることでFlutterライフがより楽しくなると個人的には思います。また汎用的に現場でも活かせる機会が増えます。
どなたかの参考になれば幸いです。
ではまた。



コメント