FinalとConstフィールド
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 18/110。
クラスでフィールドを宣言する際、初期化後に値が変更可能かどうかを制御するために final または const を使用できます。どちらも不変の値を作成しますが、その仕組みは異なります。
final フィールドは一度しか設定できませんが、その値は実行時に決定されます。宣言時、またはコンストラクタを通じて割り当てることができます。
class Person {
final String name;
final DateTime createdAt = DateTime.now();
Person(this.name);
}
Person p = Person('Alice');
// p.name = 'Bob'; // エラー: finalフィールドを再代入することはできませんname はオブジェクトの作成時に設定され、createdAt は現在の時刻をキャプチャします。初期化後、両方の値はロックされます。
static const フィールドは、コンパイル時に値が確定している必要があります。これはクラス自体に属し、すべてのインスタンス間で共有されます:
class Circle {
static const double pi = 3.14159;
final double radius;
Circle(this.radius);
double get area => Circle.pi * radius * radius;
}主な違いは次のとおりです。final フィールドは実行時に計算された値(DateTime.now() など)を保持できますが、const はコンパイル時定数を必要とします。インスタンスフィールドを直接 const にすることはできません。クラスレベルでは static const のみが許可されます。
チャレンジ
簡単final フィールドと static const フィールドの違いを実演する商品カタログシステムを構築しましょう。不変(immutable)なプロパティと共有の構成値を持つ商品を作成します。
コードを2つのファイルに整理します:
product.dart: 店舗のアイテムを表すProductクラスを定義します。クラスには以下のものを含めてください:- すべての商品で共有される
static const double taxRateを0.08(8%の税率)に設定 static const String currencyを'USD'に設定- 商品の名前のための
final String name(コンストラクタ経由で設定) - 商品の基本価格のための
final double basePrice(コンストラクタ経由で設定) - プレフィックスと商品名を組み合わせた
final String sku(stock keeping unit)。初期化リストで'SKU-'の後に大文字の名前を続けて計算します nameとbasePriceを受け取るコンストラクタ- 税込み価格を計算するゲッター
priceWithTax - 商品情報を表示する
display()メソッド
- すべての商品で共有される
main.dart: 商品クラスをインポートし、2つの商品を作成します:- 基本価格
999.99の'Laptop' - 基本価格
29.99の'Mouse'
display()を呼び出します。- 基本価格
display() メソッドは、以下の正確な形式で出力する必要があります:
[sku] - [name]: [basePrice] [currency] (with tax: [priceWithTax] [currency])表示する際、priceWithTax は toStringAsFixed(2) を使用して小数点以下2桁に丸めてください。
期待される出力:
SKU-LAPTOP - Laptop: 999.99 USD (with tax: 1079.99 USD)
SKU-MOUSE - Mouse: 29.99 USD (with tax: 32.39 USD)チートシート
実行時に一度だけ設定され、その後変更できないフィールドには final を使用します。クラスのすべてのインスタンスで共有されるコンパイル時定数には static const を使用します。
final フィールドは実行時に設定され、宣言時またはコンストラクタで初期化できます:
class Person {
final String name;
final DateTime createdAt = DateTime.now();
Person(this.name);
}static const フィールドは、コンパイル時定数である必要があり、クラス自体に属します:
class Circle {
static const double pi = 3.14159;
final double radius;
Circle(this.radius);
double get area => Circle.pi * radius * radius;
}final フィールドの値は、初期化リストで計算することができます:
class Product {
final String name;
final String sku;
Product(this.name) : sku = 'SKU-${name.toUpperCase()}';
}主な違い:
final: 実行時の値、インスタンスごとに異なる可能性があるstatic const: コンパイル時定数、すべてのインスタンスで共有される- インスタンスフィールドを直接
constにすることはできません。static constのみが許可されます。
自分で試してみよう
import 'product.dart';
void main() {
// TODO: 基本価格 999.99 で 'Laptop' という名前の Product を作成してください
// TODO: 基本価格 29.99 で 'Mouse' という名前の Product を作成してください
// TODO: 各製品に対して順番に(最初に 'Laptop'、次に 'Mouse')display() を呼び出してください
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ