Flutterプログラミング

【アプリ開発入門】Flutter|Dartのクラスを理解する

Flutter

こんにちは。ゲームプログラマーのメガネです。

この記事では、Flutter(Dart)のクラスについて解説します。わかりやすく解説していますので、ぜひ読んでいってください。

クラスとは設計図のこと

オブジェクト思考言語でクラスは避けて通れない概念です。

クラスは「もの」の設計図をイメージしてもらえれば良いと思います。クラスを使用するときは、設計図をもとにインスタンスを作成します。

犬をあらわすDogクラスを例にします。犬には犬種と名前、年齢という個々のパラメータがあります。ちわわとかちびとか1歳とかですね。同じDogのインスタンスでも、パラメータの設定次第で秋田犬にもなりますし、ドーベルマンにもなります。

クラスの作成方法

クラスを作成するときは、classキーワードを書いて、その右にクラス名を記述します。

クラス名の1文字目は大文字の英字で、2文字目以降は英数字または_です。{}で囲んだ範囲がクラスになります。

class Dog {
}

メンバー変数とメソッド

メンバー変数はfinallateなどの修飾子、変数の型、変数名の順に記述します。また、=でつないで初期値を設定することができます。

/// メンバー変数
final String name = "pochi";

メソッドは戻り値の型、変数名の順に並びます。()の中には複数個の引数を書くことができて、呼び出し元から変数を受け取ることができます。メソッドの中身は{}の中に記述します。

戻り値の型がvoid以外の場合は、returnで戻り値を返す必要があります。この例では、nameを返しています。

/// メンバー関数
String getName() {
  return name;
}

コンストラクタ

コンストラクタは、クラスのインスタンスが生成されたときに一度だけ実行されるメソッドです。クラスの変数を初期化し、クラスの状態を初期状態に設定します。final修飾子のついた変数に外から値を代入したときは、コンストラクタで初期化します。

この例では、外から文字列を受け取ってnameに設定しています。

class Dog {
  Dog(this.name);
  final String name;
}

任意引数

[]で囲んだ部分は任意引数です。コンストラクタの呼び出し時に省略することができます。省略されるとageは初期値のnullになります。

class Dog {
  Dog(this.name, [this.age]);
  final String name;
  int? age;
}

任意引数には、以下のように=で初期値を設定することができます。

class Dog {
  Dog(this.name, [this.age = 1]);
  final String name;
  int? age;
}

名前付き引数

{}で囲むと名前付き引数になります。

名前付き引数にしておくことで、呼び出し側で名前を指定しないといけなくなります。名前付き引数を使用することで、引数の誤りを防ぐことができます。

requiredを指定することで、その引数は省略不可になります。

class Dog {
  Dog({required this.name});
  final String name;
}

この場合は、呼び出しもとでは以下のように書きます。

void main() {
  var dog = Dog(name: "pochi");
}

名前付きコンストラクタ

コンストラクタに.名前を指定することで、名前付きのコンストラクタになります。

class Dog {
  Dog.shibainu() : kind() = 'shibainu';
  final String kind;
}

以下のように呼び出します。

void main() {
  var dog = Dog.shibainu();
}

プライベート変数とメソッド

上記で使っていたnameはパブリック変数で、クラスの外から自由にアクセスできます。外から不用意に書き換えることができてしまうので、思わぬバグにつながる可能性があります。それでは困るので、クラスの外からアクセスできないように、nameをプライベート変数にします。

プライベートにする場合は、変数名の先頭に_を付けるだけです。name_nameに変更します。

メソッドも同様に_からはじまる名前にすることで、クラスの外からアクセスできないようになります。

class Dog {
  Dog({this._name});

  /// メンバー変数
  final String _name;

  /// メンバー関数
  String getName() {
    return _name;
  }
}

getterとsetter

変数を取得するだけ、設定するだけの場合は、メソッドよりもgetsetを使った方が効率が良いです。

getsetも定義すると、パブリック変数と何が違うの?と思われるかもしれません。setで変数を上書きするだけだと何も変わらないのですが、setはメソッド同様にエラー処理を書くことができます。そのため、パブリック変数に直接アクセスされるよりは、安全なコードにできます。

クラスのメンバー変数はプライベートで定義しておいて、外から変更する必要のある場合はgetsetを定義するのが推奨です。

class Dog {
  Dog({this._name});

  /// メンバー変数
  final String _name;

  /// getter
  String get name => name;

  /// setter
  set name(String n) {
    if (n.length > 0) {
      _name = n;
    } else {
      print('1文字以上の名前を設定してください');
    }
  }
}

クラス変数とメソッド

クラス変数は静的変数とも呼びます。クラスのインスタンスごとの変数ではなく、クラス全体で状態をあらわす際に使用します。定数を宣言するときにも便利です。

class Dog {
  static const int NumberOfDogBreeds = 194;
}

メソッドもstaticを付けて宣言します。

class Dog {
  static const int getNumberOfDogBreeds() => 194;
}

まとめ

オブジェクト思考言語でクラスは最初に覚えるべき概念です。

すぐに理解できなくても、プログラミングをしていると徐々に理解できていくはずです。経験を積んでいくと、あるときを境に急に「完全に理解した」状態になると思いますので、あきらめずにプログラムを続けてみてください。

コメント