Menu
Coddy logo textTech

クラスにおける Null Safety

CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 28/110。

クラスを設計する際、どのフィールドが必須で、どのフィールドがオプションであるかを決定する必要があります。Null safetyは、インスタンス変数の宣言方法やコンストラクタの記述方法に影響を与えます。

Null 非許容フィールドは、コンストラクタの本体が実行される前に初期化される必要があります。これは、初期化子リスト、コンストラクタのパラメータ、またはデフォルト値を使用して行うことができます。

class User {
  String name;           // 初期化する必要があります
  String? bio;           // オプション - nullを許容
  int age = 0;           // デフォルト値あり
  
  User(this.name);       // nameは引数を介して初期化されます
}

null許容フィールドについては、デフォルトでnullになるため、初期化しないままにしておくことができます。これは、オプションのデータに便利です:

class Product {
  String title;
  String? description;   // 任意の製品説明
  double? discount;      // デフォルトでは割引なし
  
  Product(this.title);
}

var item = Product('Laptop');
print(item.description);  // null
print(item.discount);     // null

null許容(nullable)フィールドにアクセスする際は、これまでに学んだnull演算子を使用してください:

class Order {
  String id;
  User? customer;
  
  Order(this.id);
  
  String getCustomerName() {
    return customer?.name ?? 'Guest';
  }
}

名前付き引数における required キーワードは、呼び出し側が必須の値を確実に提供するようにします:

class Account {
  String email;
  String? phone;
  
  Account({required this.email, this.phone});
}

var acc = Account(email: 'test@mail.com');  // phoneは任意です

nullable(ヌル許容)フィールドとnon-nullable(ヌル非許容)フィールドを慎重に選択することで、どのデータが必須で、どのデータがオプションであるかを明確に伝えるクラスを作成できます。

challenge icon

チャレンジ

簡単

ヌル安全(null safety)を活用し、必須フィールドとオプションフィールドを適切に組み合わせたクラス設計を実演する、ホテルの予約システムを構築しましょう。

コードは以下の2つのファイルに分けて構成します:

  • reservation.dart: ホテルの予約を表す Reservation クラスを定義します。すべての予約には特定の必須情報が必要ですが、一部の詳細はゲストが提供する場合もしない場合もあるオプション項目です。クラスには以下の要素を含めてください:
    • 非ヌル許容(non-nullable)の String guestName - すべての予約にはゲスト名が必要です
    • 非ヌル許容(non-nullable)の int roomNumber - すべての予約には部屋番号が割り当てられる必要があります
    • 非ヌル許容(non-nullable)の int nights(デフォルト値は 1) - 最低宿泊数は1泊です
    • ヌル許容(nullable)の String? specialRequests - ゲストは特別なリクエストを持つ場合があります
    • ヌル許容(nullable)の DateTime? checkInTime - 正確な到着時刻は不明な場合があります
    • guestNameroomNumberrequired を指定した名前付きパラメータを使用するコンストラクタ。nights はデフォルト値を持つオプション項目とします
    • getRequestsSummary() メソッド:特別なリクエストが提供されている場合はそれを返し、そうでない場合は ?? 演算子を使用して 'No special requests' を返します
    • getArrivalInfo() メソッド:?. を使用してチェックイン時刻の文字列表現を返し、設定されていない場合は null を返します
    • printConfirmation() メソッド:予約の詳細を表示します
  • main.dart: 予約クラスをインポートし、必須データとオプションデータのさまざまな組み合わせを示す予約を作成します:
    • ゲスト 'Sarah Johnson'、部屋番号 101、宿泊数 3、特別リクエスト 'Late checkout'、チェックイン時刻 DateTime(2024, 6, 15, 14, 30) の予約を作成します
    • ゲスト 'Mike Chen'、部屋番号 205(宿泊数はデフォルトを使用)、特別リクエスト 'Extra pillows' のみの予約を作成します
    • ゲスト 'Emma Davis'、部屋番号 310、宿泊数 2(両方のオプションフィールドは null のまま)の予約を作成します
    • 各予約に対して順番に printConfirmation() を呼び出し、次に getArrivalInfo() を使用して Arrival: [result] と出力します

printConfirmation() メソッドは、以下の形式で出力する必要があります:

=== Reservation Confirmed ===
Guest: [guestName]
Room: [roomNumber]
Nights: [nights]
Requests: [getRequestsSummary()]

期待される出力:

=== Reservation Confirmed ===
Guest: Sarah Johnson
Room: 101
Nights: 3
Requests: Late checkout
Arrival: 2024-06-15 14:30:00.000
=== Reservation Confirmed ===
Guest: Mike Chen
Room: 205
Nights: 1
Requests: Extra pillows
Arrival: null
=== Reservation Confirmed ===
Guest: Emma Davis
Room: 310
Nights: 2
Requests: No special requests
Arrival: null

チートシート

非 null 許容フィールドはコンストラクタの本体が実行される前に初期化される必要がありますが、null 許容フィールドは未初期化のままにすることができます(デフォルトは null です)。

class User {
  String name;           // 初期化が必要
  String? bio;           // オプション - デフォルトは null
  int age = 0;           // デフォルト値あり
  
  User(this.name);
}

オプションのデータには null 許容フィールドを使用します:

class Product {
  String title;
  String? description;   // オプション
  double? discount;      // オプション
  
  Product(this.title);
}

var item = Product('Laptop');
print(item.description);  // null

null 許容フィールドには null 許容演算子を使用してアクセスします:

class Order {
  String id;
  User? customer;
  
  Order(this.id);
  
  String getCustomerName() {
    return customer?.name ?? 'Guest';
  }
}

必須の値には、名前付きパラメータで required キーワードを使用します:

class Account {
  String email;
  String? phone;
  
  Account({required this.email, this.phone});
}

var acc = Account(email: 'test@mail.com');

自分で試してみよう

import 'reservation.dart';

void main() {
  // TODO: 'Sarah Johnson' の予約を作成する
  // 101号室、3泊、特別リクエスト: 'Late checkout'
  // チェックイン時間: DateTime(2024, 6, 15, 14, 30)
  
  // TODO: 'Mike Chen' の予約を作成する
  // 205号室、デフォルトの宿泊数を使用、特別リクエスト: 'Extra pillows'
  // チェックイン時間の指定なし
  
  // TODO: 'Emma Davis' の予約を作成する
  // 310号室、2泊、特別リクエストなし、チェックイン時間なし
  
  // TODO: 各予約に対して順番に以下を行う:
  // 1. printConfirmation() を呼び出す
  // 2. getArrivalInfo() を使用して 'Arrival: [result]' を出力する
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン