質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

1回答

808閲覧

Flutter, "Widget build(BuildContext context) {}" の冒頭Widgetはなぜ明示的に記述するのか

fukazume

総合スコア78

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

1グッド

2クリップ

投稿2019/01/24 03:15

編集2019/01/25 04:48

Flutter新規プロジェクトを作成したときに生成されるデフォルトmain.dartのbuildメソッドについて。

■調査した内容
以下の公式ドキュメントやMedium投稿等を読みましたが、直接的に当質問に対応する箇所が見当たりませんでした。概念は理解したのですが、実体的な理解までは至っておりません。

Widget — State — BuildContext — InheritedWidget(Medium)
Widget class
Introduction to widgets
BuildContext class
build method

■現状の理解
画面描画するときにこのbuildメソッドを使うんだな、という程度のグラグラな認識です。

■質問

  1. 冒頭のabstract class "Widget" (だけ?)はなぜ明示的に宣言されているのですか?一応、"Widget"部を削除してもコードが正常動作することは確認しました。

  2. build(BuildContext context)は、abstract class BuildContextとcontextがbuildメソッドの引数という構造でしょうか?

  3. 上記、各トークンの意味を踏まえ、この@override、Widgetクラス、buildメソッドを平易な表現でご解説いただけると大変ありがたいです。どうぞよろしくお願い申し上げます。

Flutter

1@override 2Widget build(BuildContext context){ 3 return MaterialApp( 4 title: 'Flutter Demo', 5 theme: ThemeData( 6 primarySwatch: Colors.blue, 7 ), 8 home: MyHomePage(title: 'Flutter Demo Home Page'), 9 ); 10}
myzer👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

質問の順序が前後しますが、回答します

2

build(BuildContext context)は、abstract class BuildContextとcontextがbuildメソッドの引数という構造でしょうか?

  • これはBuildContext型の引数contextbuildメソッドの引数で、引数としては一つです

この質問から、質問者さんは静的型付け言語にあまり多く触れられたことがないかと推察いたしますが、
静的型付け言語では基本的に変数などを<クラス(型)名> <変数名>と宣言します。

dartは、コード的にはjavascriptのような形で、部分的にクラス(型)名を書かなくても動作するようになっていますが、これは動的型付けだからではなく、型推論のある静的型付け言語だからです。

まず、dartの仕様を読んでみることをお勧めします

1

冒頭のabstract class "Widget" (だけ?)はなぜ明示的に宣言されているのですか?

これにはまず@overrideの説明をします。
記載のあるbuildメソッドは、おそらく
class <クラス名> extends StatelessWidget

class <クラス名> extends State<クラス名2>
のような宣言をされたクラス内で定義されたメソッドであるはずです。
ここでextendsはクラスの拡張を示していて、
一般的に、上の例ではStatelessWidget, 下の例ではState<クラス名2>親クラス と言います。
それと対応して例で定義されている<クラス名>というクラスは 子クラス と言います。
子クラスは基本的に親クラスに定義されたメソッドを受け継いで持っており、
@overrideが記載されているメソッドというのは、親クラスに定義されたメソッドを上書きしますよ、という宣言です。

@overrideは無くてもメソッド宣言が親クラスにあるものと一致していれば勝手に上書きになるのですが、きちんとつけておくことで何かと便利なのでつけます。
@overrideがついているのにも関わらず、親クラスに同名のメソッドがない時などに、警告を出してくれたりします。
親クラスのメソッドを上書きしたつもりが、誤字で上書きできていなかったケースなどに気づけます。

さて、ここから冒頭のWidgetの戻り値の型宣言がなぜ明示的にされていて、
かつ消しても動いたかについてですが、

dartではメソッドの戻り値の型宣言を省略すると、通常dynamicという特殊な型を戻り値とします。
(ざっくり言うと戻り値の型がなんでも良いという状態です。詳しくはdartの言語仕様を確認してください。)

dartでは仕組み上、1つのクラス内に同じ名前のメソッドを複数持つことができません。
(例えばJavaではメソッド名が異なっても、引数の個数や型などが違う複数の同名メソッドを持つことができます)

少し複雑になりましたが整理すると

  • extendsキーワードでクラスを拡張すると、子クラスは親クラスと同じメソッドをデフォルトで持っていることになる
  • dartでは1つのクラス内に同じ名前のメソッドを複数持つことができない

という点が重要で、Widgetの宣言を消したときに起こっているのは

  • 普通は戻り値の型の指定がない場合はdynamicが戻り値の型とされる
  • だが、今回は親クラスに同名のメソッド(build)があるため、子クラスにもデフォルトで引き継がれている
  • 1つのクラス内にdynamic型を返すbuildメソッドとWidget型を返すbuildメソッドは同居できないので、親クラスの宣言が有効とされた
  • したがって、明示的に書いていなくとも、buildメソッドはWidget型を返すものとして解釈され、Flutter全体としてもエラー無く動作した

です

3

上記、各トークンの意味を踏まえ、この@override、Widgetクラス、buildメソッドを平易な表現でご解説いただけると大変ありがたいです。

  • @overrideは上でも説明した通り、親クラスのメソッドを上書きしますよという宣言です
    • なくても動きますが、便利なのと、お作法的にきちんと書くことがほとんどです。
  • Widgetクラスは、flutter内では画面に描画するものの基本単位となるクラスです。
    • 画面に表示するものはWidget及びその子クラスを拡張してクラスとして作成します
      • StatelessWidget, StatefulWidgetWidgetの子クラスです
        • したがって、StatelessWidgetを拡張して作ったクラスも間接的にWidgetの子クラスと言えます
  • buildクラスはそのクラスを画面描画するときにFlutterのフレームワークが呼び出してくれるメソッドです。
    • ここで描画したいものをreturnすることで、画面にパーツが描画されます。

以上、変に複雑になりましたが回答とさせていただきます。

投稿2019/04/10 05:07

keitatomozawa

総合スコア81

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fukazume

2019/07/11 08:28

完璧なご回答をいただいたことに、私のミスで今まで気付きませんでした。大変申し訳ございません。お察しの通り、私のような初心者の分かりにくい質問に対してもわかりやすくお教えいただき、誠にありがとうございました。また質問者が最適な順序で理解できるようにご回答も再構成してくださったので、とても読み進めやすかったです。改めてお詫び申し上げるとともに、丁寧なご回答に深く感謝申し上げます。m(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問