【Flutter】super.keyとは何か?superを使って親クラスのメソッドを呼ぶ方法について

Flutter基礎

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を継承しているMyWidget
  • MyWidgetのコンストラクタで 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(Dart)で頻繁に使用される @overrideとはなにか

      Flutterでも使われる例

      Flutterの標準でもこの仕組みが使われています。

      例:State クラスの initState

      @override
      void initState() {
        super.initState(); // 親 State の初期化も必ず行う
        // 子クラスの初期化処理
      }

      ここで super.initState() を忘れると親クラスの初期化が行われず、動作に問題を起こすため.superが必要になります。

      つまり、

      • superを使って親クラスのメソッドを呼ぶことで、子クラスでオーバライドした新しい処理と親クラスの元の処理の両方が実行が可能

      になります。

      これで2つ目の「superで親クラスのメソッドを呼ぶ」についても親クラスや子クラスで柔軟にメソッドを使い分けたい時に有効に使えることが理解できたかなと思います。

      最後に

      簡単ではありますが、superについて解説していきました。理解を深めることでFlutterライフがより楽しくなると個人的には思います。また汎用的に現場でも活かせる機会が増えます。

      どなたかの参考になれば幸いです。

      ではまた。

      コメント

      タイトルとURLをコピーしました