[Flutter] Dartのクラス

2021-04-01 hit count image

Flutterでアプリを開発するためFlutterの開発言語であるDartについて説明します。今回のブログポストではDartでクラスを使う方法について説明します。

ブログシリーズ

このブログはシリーズで作成しております。下記のリンクを参考して他のブログポストも確認してみてください。

概要

今回のブログポストではDartでクラスを使う方法について説明します。

このブログポストで紹介するソースコードは下記のリンクで確認できます。

クラス

クラスを宣言する時、クラス名は大文字で始めます。クラスはメンバー変数やメンバー関数を持ってることができます。

class Fruit {
  String name = 'Apple';

  void printName() {
    print('My name is ${this.name}!');
  }
}

void main() {
  Fruit fruit = new Fruit();
  fruit.printName();
  fruit.name = 'Banana';
  fruit.printName();
}

クラスのメンバー変数とメンバー関数は.を使って使うことができます。

コンストラクト

クラスはコンストラクト(Constructor)を持ってます。コンストラクトはクラスと同じ名前で宣言をします。

class Fruit {
  String? name;
  String? color;

  Fruit(String name, String color) {
    this.name = name;
    this.color = color;
  }

  void printName() {
    print('My name is ${this.name}(${this.color})!');
  }
}

void main() {
  Fruit fruit = new Fruit('Apple', 'Red');
  fruit.printName();
}

クラスのコンストラクトは下記のように宣言することもできます。

class Fruit {
  String? name;
  String? color;

  Fruit(String name, String color)
      : this.name = name,
        this.color = color;

  void printName() {
    print('My name is ${this.name}(${this.color})!');
  }
}

void main() {
  Fruit fruit = new Fruit('Apple', 'Red');
  fruit.printName();
}

コンストラクトにもNamedパラメーターを使うことができます。

class Fruit {
  String? name;
  String? color;

  Fruit({String? name, String? color})
      : this.name = name,
        this.color = color;

  void printName() {
    print('My name is ${this.name}(${this.color})!');
  }
}

void main() {
  Fruit fruit = new Fruit(color: 'Red', name: 'Apple');
  fruit.printName();
}

DartではNamedコンストラクトと言う機能も提供しております。

class Fruit {
  String? name;
  String? color;

  Fruit({String? name, String? color})
      : this.name = name,
        this.color = color;

  // Named Constructor: You can use any name on [fromMap]
  Fruit.fromMap(Map<String, String> fruit)
      : this.name = fruit['name'],
        this.color = fruit['color'];

  void printName() {
    print('My name is ${this.name}(${this.color})!');
  }
}

void main() {
  Fruit fruit = new Fruit(name: 'Apple', color: 'Red');
  fruit.printName();

  Fruit fruitFromMap = new Fruit.fromMap({'color': 'Red', 'name': 'Apple'});
  fruitFromMap.printName();
}

final

クラスでfinalを使ってインスタンスを生成する時、定数を設定することができます。

class Fruit {
  final String? name;
  final String? color;

  Fruit({String? name, String? color})
      : this.name = name,
        this.color = color;

  void printName() {
    print('My name is ${this.name}(${this.color})!');
  }
}

void main() {
  Fruit fruit = new Fruit(name: 'Apple', color: 'Red');
  fruit.printName();

  fruit.name = 'Kiwi'; // << ERROR
}

Private変数

Dartでは変数名の前に_を追加してPrivate変数を作ることができます。クラスの中だけPrivate変数が使える他の言語とは違って、Dartではクラスが定義されたファイル中でPrivate変数にアクセスすることができます。

class Fruit {
  String? _name;

  Fruit(String name) : this._name = name;

  void printName() {
    print('My name is ${this._name}!');
  }
}

void main() {
  Fruit fruit = new Fruit('Apple');
  fruit.printName();
  // Print Private variable
  // It's possibe because of same file.
  print(fruit._name);
}

GetterとSetter

クラスがPrivate変数を持って流場合、当該変数についてGetterSetterを生成することができます。GetterとSetterの名前は何でもつけることができますが、普通Privateの変数名で_を抜いた名前を使います。

class Fruit {
  String? _name;

  Fruit(String name) : this._name = name;

  String get name {
    return this._name ?? '';
  }

  void set name(String name) {
    this._name = name;
  }
}

void main() {
  Fruit fruit = new Fruit('Apple');

  print(fruit.name); // Getter
  fruit.name = 'Banana'; //Setter
  print(fruit.name);
}

継承

クラスは他のクラスを継承(Inheritance)することができます。継承する時はextendsキーワードを使います。Dartでは1つのクラスだけ継承することができるし、親クラスにアクセスする時はsuperキーワードを使います。

class Food {
  String? name;

  Food(String name) : this.name = name;

  void printName() {
    print('My name is ${this.name}!');
  }
}

// Inheritance
class Fruit extends Food {
  // Call parent constructor
  Fruit(String name) : super(name);

  void printFruit() {
    print('${this.name} is Fruit!');
  }
}

void main() {
  Fruit fruit = new Fruit('Apple');
  fruit.printName();
  fruit.printFruit();

  Food food = new Food('Rice');
  food.printName();
  food.printFruit(); // << ERROR
}

オーバーライド

子クラスで親クラスの関数をオーバーライド(Override)することができます。オーバーライドとは親クラスで定義された関数を子クラスで再定義することを意味します。

class Food {
  String? name;

  Food(String name) : this.name = name;

  void printName() {
    print('My name is ${this.name}!');
  }
}

class Fruit extends Food {
  Fruit(String name) : super(name);

  void printName() {
    super.printName();
    print('${this.name} is Fruit!');
  }
}

void main() {
  Fruit fruit = new Fruit('Apple');
  fruit.printName();

  Food food = new Food('Rice');
  food.printName();
}

オーバーライドをする時、@overrideキーワードを使ってもうちょっと明確オーバーライドを指定することできます。

class Food {
  String? name;

  Food(String name) : this.name = name;

  void printName() {
    print('My name is ${this.name}!');
  }
}

class Fruit extends Food {
  Fruit(String name) : super(name);

  @override
  void printName() {
    print('${this.name} is Fruit!');
  }
}

void main() {
  Fruit fruit = new Fruit('Apple');
  fruit.printName();

  Food food = new Food('Rice');
  food.printName();
}

静的メンバー

Dartでも静的メンバー変数と関数を使うことができます。静的メンバーを宣言する時にはstaticキーワードを使います。

class Food {
  static String? kind;
  String? name;

  Food(String name) : this.name = name;

  static printAll(String name, String kind) {
    print('${name} is ${kind}!');
  }

  void printName() {
    print('My name is ${this.name}! I am ${kind}!');
  }

}

void main() {
  Food apple = new Food('Apple');
  apple.printName();
  Food banana = new Food('Banana');
  banana.printName();

  Food.kind = 'Fruit';
  apple.printName();
  banana.printName();

  Food.printAll('Apple', 'Red Fruit');
}

インタフェース

Dartではクラスを使ってインタフェース(Interface)を定義します。インタフェースはクラスを定義する時、必ず定義する変数や関数を指定するとき使います。他の言語とは違ってDartではInterfaceと言うキーワードの代わりでclassを使ってインタフェースを定義し、implementsを使って使います。

class Food {
  String? name;

  void printName() {}
}

class Fruit implements Food {
  String? name;

  Fruit(String name) : this.name = name;

  void printName() {
    print('My name is ${this.name}!');
  }
}

void main() {
  Fruit fruit = new Fruit('Apple');
  fruit.printName();
}

インタフェースではクラスで使う関数だけ定義して、関数の内容は作成しません。インタフェースを使うクラスにその関数の内容を作成します。

Cascade Operator

DartにはCascade Operatorと言う機能が提供されております。クラス以外にも使えますが、クラスで説明することが簡単なので、ここで紹介します。

class Fruit {
  String? name;
  String? color;

  Fruit(String name, String color)
      : this.name = name,
        this.color = color;

  void printAll() {
    print('My name is ${this.name}(${this.color})!');
  }

  void printName() {
    print('My name is ${this.name}!');
  }

  void printColor() {
    print('I am ${this.color}');
  }
}

void main() {
  Fruit fruit = new Fruit('Apple', 'Red');
  fruit.printAll();
  fruit.printName();
  fruit.printColor();

  new Fruit('Apple', 'Red')
    ..printAll()
    ..printName()
    ..printColor();
}

例題ようにCascade Operator(..)を使うとクラスを宣言する時、クラスの関数も同時に使うことができます。

完了

これでFlutterでアプリを開発するためDartで使えるクラスについてみてみました。Dartもオブジェクト指向プログラミング(Object-Oriented Programming, OOP)なので、クラスを提供するし、他のOOP言語で活用できる機能をほとんど提供しております。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

Posts