Mixinの作成
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 51/110。
ミックスインが何であるかを理解したところで、それらを適切に作成する方法を見ていきましょう。ミックスインは、class の代わりに mixin キーワードを使用して宣言されます。
mixin Logging {
void log(String message) {
print('[LOG] $message');
}
void logError(String error) {
print('[ERROR] $error');
}
}ミックスインは、クラスと同じように、メソッド、プロパティ、さらにはゲッターやセッターを含めることができます。しかし、1つ重要なルールがあります。ミックスインはコンストラクタを持つことができません。ミックスインは直接インスタンス化されるのではなく、「ミックスイン」されることを目的としているため、初期化ロジックは必要ありません。
mixin Timestamped {
DateTime createdAt = DateTime.now();
String get formattedTime => createdAt.toString();
void printTimestamp() {
print('Created at: $formattedTime');
}
}
class Document with Timestamped {
String title;
Document(this.title);
}
void main() {
var doc = Document('Report');
doc.printTimestamp(); // mixinのメソッドを使用
print(doc.createdAt); // mixinのプロパティを使用
}with を使用してミックスインを適用すると、そのすべてのメンバがクラスの一部になります。クラスはそれらを直接使用でき、そのクラスのインスタンスを持つコードも同様に使用できます。これにより、ミックスインは継承階層の複雑さを伴わずに、再利用可能な機能を追加するためのクリーンな方法となります。
チャレンジ
簡単メソッド、プロパティ、ゲッターを持つミックスインの作成方法を紹介するメッセージングシステムを構築しましょう。異なるタイプのメッセージにフォーマット機能を追加するミックスインを設計します。
コードは2つのファイルに分けて構成します:
messaging.dart: ここでミックスインとメッセージクラスを定義します:- 以下の内容を含む
Formattableミックスイン:'>>>'で初期化されたString prefixプロパティ' | 'を返すゲッターseparator- 文字列
[prefix][separator][text]を返すメソッドformat(String text) **[text]**を返すメソッドformatBold(String text)
Formattableミックスインを使用するTextMessageクラス。コンストラクタを持つString senderプロパティを追加します。[sender]: [content]を引数にしてformat()を呼び出した結果をプリントするsend(String content)メソッドを含めます。- 同じく
Formattableミックスインを使用するAlertMessageクラス。コンストラクタを持つString levelプロパティを追加します。[[level]] [formatBold(content)]を引数にしてformat()を呼び出した結果をプリントするalert(String content)メソッドを含めます。
- 以下の内容を含む
main.dart: メッセージングファイルをインポートし、両方のメッセージタイプがミックスインからどのようにフォーマット機能を得るかを実演します:- sender が
'Alice'のTextMessageを作成します - level が
'WARNING'のAlertMessageを作成します - テキストメッセージに対して
send('Hello there!')を呼び出します - アラートメッセージに対して
alert('System overload')を呼び出します
- sender が
このミックスインは、ミックスインがデフォルト値を持つプロパティ、値を計算するゲッター、そして互いに呼び出すこともできる複数のメソッドを含めることができることを示しています。両方のメッセージクラスは、with キーワードを使用するだけで、これらすべての機能を得ることができます。
期待される出力:
>>> | Alice: Hello there!
>>> | [WARNING] **System overload**チートシート
Mixinは、classの代わりにmixinキーワードを使用して宣言されます:
mixin Logging {
void log(String message) {
print('[LOG] $message');
}
void logError(String error) {
print('[ERROR] $error');
}
}Mixinにはメソッド、プロパティ、ゲッター、セッターを含めることができますが、コンストラクタを持つことはできません:
mixin Timestamped {
DateTime createdAt = DateTime.now();
String get formattedTime => createdAt.toString();
void printTimestamp() {
print('Created at: $formattedTime');
}
}withキーワードを使用して、Mixinをクラスに適用します。すべてのMixinメンバーがクラスの一部になります:
class Document with Timestamped {
String title;
Document(this.title);
}
void main() {
var doc = Document('Report');
doc.printTimestamp(); // Mixinのメソッドを使用
print(doc.createdAt); // Mixinのプロパティを使用
}自分で試してみよう
import 'messaging.dart';
void main() {
// TODO: 送信者を 'Alice' として TextMessage を作成する
// TODO: レベルを 'WARNING' として AlertMessage を作成する
// TODO: text message に対して send('Hello there!') を呼び出す
// TODO: alert message に対して alert('System overload') を呼び出す
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ