🤔

dartで個人的に気になったものまとめ

に公開

クラスの部類

implementsとは

親クラスで指定したメソッドを子クラスで強制的実装するために使う。
インターフェースと呼ばれたりしている。

abstract class Animal {
  void makeSound();
  void move();
}

class Dog implements Animal {
  
  void makeSound() {
    print('ワンワン');
  }

  
  void move() {
    print('走る');
  }
}

Exceptionのインターフェースは、意図が違う

下記コードは、メソッドを強制しているものではなさそうだったので調査した。

class AuthException implements Exception {
 // メソッドが一個もない...
}

実際、親クラスのExceptionは、メソッドはない。
単純に、このクラスが例外であることを示すものである。
「マーカーインターフェース」と呼ばれている。

mixinとは

複数のクラスを継承できるようにしてくれるもの。

main.dart
void main() {
  Duck().swim();
  
  Duck().fly();
  
}

// mixinで継承するクラス
mixin Fish {
  void swim () {
    print("by swimming");
  }
}

mixin Bird {
  void fly () {
    print("by flying");
  }
}

// withで継承したいクラスを指定
class Duck with Bird,Fish{
}

enumsとは

命名された定数値を表すために使われるクラス。
下記公式の説明を翻訳して、引用。

列挙型は、しばしば列挙または列挙型と呼ばれ、固定数の定数値を表すために使われる特別な種類のクラスである。

https://dart.dev/language/enums

条件分岐で使われることが多いと思われる。
下記が使用例。

void main() {
  Color favoriteColor = Color.blue;
  // blue
  printcolor(favoriteColor);
}

void printcolor (Color selectColor) {
  if(selectColor == Color.red){
    print('red');
  } 
  if (selectColor == Color.blue) {
    print('blue');
  } 
  if (selectColor == Color.green) {
    print('green');
  }
}

enum Color {
  red,
  blue,
  green,
}

抽象クラス

抽象クラスは、インスタンス化ができないクラスで、継承されることが目的とされたクラス。
つまり、サブクラスで記述してほしいメソッドを管理できる。

main.dart
abstract class Template {
  int? number1;
  int? number2;

  void sum(int number1,int number2);
}

class Sum extends Template {
  // sumメソッドoverrideして実装を変えることもできる。
  
  void sum (int number1,int number2) {
    print(number1 + number2);
  }
}

void main() {
  Sum().sum(3,4);
}

装飾子

static

クラスのインスタンス化を行わなくても、メソッドや変数を呼び出せる。

main.dart
void main() {
  // クラスをインスタンス化せずに、メソッド呼び出せる
  Human.action("cooking");
}

class Human {
  static void action (String action) {
    print(action);
  }
}

late

変数の宣言時に初期値を与えず、後から値を入れること初期化ができる。

main.dart
void main() {
  Greeting greeting = Greeting();
  // _wordに値を入れずに表示しようとするとエラーが起きる。
  greeting.hello();
  // hello
  greeting.wordprint();
}

class Greeting {
  late String _word;

  void hello () {
    _word = "hello";
  }

  void goodafternoon () {
    _word = "goodafternoon";
  }

  void wordprint () {
    print(_word);
  }
}

final

変数に対して、値の再代入をしないようにする。

constとの違いは何か?
finalは、初期化時なら値を変えられる。(インスタンス化するタイミングなら、値を変えられる)
constは、どのタイミングでも入れた値は変えられない。

main.dart
void main() {
  NumberBrain number = NumberBrain(4); 
  number = NumberBrain(10);
  // finalは初期化時に値を変えらる
  print(number.finalnumber);
  
  // 2つはオブジェクトなのでエラー
  // number.finalnumber = 4;
  // NumberBrain.constnumber = 4;
}

class NumberBrain {
  NumberBrain(this.finalnumber);
  final int finalnumber;

  static const constnumber = 1;
}

constは、コンパイルの時に値が決まる。
finalは、コンパイル後のプログラムの実行時に値を入れられる。ただ、入れた後は変えられない。

※finalについて公式サイトから参照

Although a final object cannot be modified, its fields can be changed. In comparison, a const object and its fields cannot be changed: they're immutable.
finalオブジェクトは変更できませんが、そのフィールドは変更できます。これに対して、constオブジェクトとそのフィールドは変更できません。
https://dart.dev/language/variables

thenメソッド

Future(非同期処理)の完了後に実行する処理を定義するために使用。
下記の例では、getDataの値を受け取ってデータを出力している。
受け取りたくない時は(_)として引数にアンダースコアを用いる。

Future<String> getData() async {
    return "データ";
}

// then を使用する場合
getData().then((result) {
    print(result); // "データ" が出力される
});

// async/await を使用する場合(同じ意味)
async {
    var result = await getData();
    print(result); // "データ" が出力される
}

as,show,hide

as

同名のメソッドとプロパティの呼び出しで、混合しないように区別できるように命名をする。
シンプルにimportしたパッケージのメソッド、プロパティを命名して使う意図もありそう。

import 'package:http/http.dart' as http;

void httpget () {
  // http.をつけないとエラーになる。
  http.get(url);
}

show&hide

showは、importしたパッケージ内の指定したメソッドのみ使えるようにする。

import 'package:http/http.dart' show get;

void httpget () {
  // getメソッドだけ使える。
  get(url);
  // showで指定していないので使えない
  put(url)
}

hideは、importしたパッケージ内の指定したメソッドを使えないようにする。

import 'package:http/http.dart' hide get;

void httpget () {
  // getメソッドだけ使えない。
  get(url);// エラー
}

Discussion