Callable クラス
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 84/110。
Dartでは、call()メソッドを実装することで、クラスのインスタンスを関数のように呼び出し可能にすることができます。これにより、インスタンスに対して直接括弧を使用するという、関数呼び出しの構文でオブジェクトを使用できるようになります。
class Multiplier {
final int factor;
Multiplier(this.factor);
int call(int value) {
return value * factor;
}
}
void main() {
var double = Multiplier(2);
var triple = Multiplier(3);
print(double(5)); // 10 - オブジェクトを関数のように呼び出す
print(triple(5)); // 15
}double(5) と記述すると、Dart は自動的に 5 を引数として call() メソッドを呼び出します。このオブジェクトは、自身の状態(factor フィールド)を保持したまま、関数のようにはたらきます。
call() メソッドは、複数のパラメータ、オプショナルなパラメータ、あるいは異なる型を返すなど、どのようなシグネチャも持つことができます:
class Greeter {
final String greeting;
Greeter(this.greeting);
String call(String name, {String punctuation = '!'}) {
return '$greeting, $name$punctuation';
}
}
void main() {
var hello = Greeter('Hello');
print(hello('Alice')); // Hello, Alice!
print(hello('Bob', punctuation: '.')); // Hello, Bob.
}呼び出し可能クラスは、関数のような動作と、状態や設定を組み合わせる必要がある場合に便利です。これらは、呼び出し間で設定を保持する必要がある、再利用可能な操作、バリデータ、または変換を作成するためによく使用されます。
チャレンジ
簡単コーラブルクラス(Callable classes)を使用して、テキストフォーマッターシステムを構築しましょう!独自の構成設定を維持しながら、関数のよう呼び出してテキストをさまざまな方法で変換できるオブジェクトを作成します。
コードを2つのファイルに整理します。
formatters.dart: テキストを変換する2つのコーラブルクラスを作成します。- テキストを接頭辞(prefix)と接尾辞(suffix)で囲む
Wrapperクラス。String prefixとString suffixを保持し、String textパラメータで呼び出されたときに、そのテキストを接頭辞と接尾辞で囲んで返すようにします。 - テキストを特定の回数繰り返す
Repeaterクラス。int times値を保持し、String textパラメータで呼び出されたときに、そのテキストを各繰り返しの間にスペースを入れて指定された回数だけ繰り返して返すようにします。
- テキストを接頭辞(prefix)と接尾辞(suffix)で囲む
main.dart: フォーマッターをインポートし、コーラブルクラスがどのように機能するかを示します。- 接頭辞
"["と接尾辞"]"を持つWrapperを作成します。 - 接頭辞
"***"と接尾辞"***"を持つ別のWrapperを作成します。 - 3回繰り返す
Repeaterを作成します。 - 最初の wrapper を
"Hello"で呼び出し、結果を出力します。 - 2番目の wrapper を
"Important"で呼び出し、結果を出力します。 - repeater を
"Go"で呼び出し、結果を出力します。 - 最後に、これらを組み合わせます。repeater を
"Dart"で呼び出した結果を引数にして最初の wrapper を呼び出し、その結果を出力します。
- 接頭辞
各フォーマッターオブジェクトが自身の構成を記憶しており、関数のように括弧を使用して直接呼び出すことができる点に注目してください。
期待される出力:
[Hello]
***Important***
Go Go Go
[Dart Dart Dart]チートシート
クラスは、call() メソッドを実装することで、関数のようによび出し可能にすることができます。
class Multiplier {
final int factor;
Multiplier(this.factor);
int call(int value) {
return value * factor;
}
}
void main() {
var double = Multiplier(2);
print(double(5)); // 10 - オブジェクトを関数のように呼び出しています
}call() メソッドは、複数のパラメータ、オプションのパラメータ、または異なる戻り値の型を持つ任意のシグネチャを持つことができます。
class Greeter {
final String greeting;
Greeter(this.greeting);
String call(String name, {String punctuation = '!'}) {
return '$greeting, $name$punctuation';
}
}
void main() {
var hello = Greeter('Hello');
print(hello('Alice')); // Hello, Alice!
print(hello('Bob', punctuation: '.')); // Hello, Bob.
}呼び出し可能なクラスは、状態や設定と組み合わせた関数のような動作を作成するのに便利です。
自分で試してみよう
import 'formatters.dart';
void main() {
// TODO: 接頭辞 "[" と接尾辞 "]" を持つ Wrapper を作成してください
// TODO: 接頭辞 "***" と接尾辞 "***" を持つ別の Wrapper を作成してください
// TODO: 3回繰り返す Repeater を作成してください
// TODO: 最初の wrapper を "Hello" で呼び出し、結果をプリントしてください
// TODO: 2番目の wrapper を "Important" で呼び出し、結果をプリントしてください
// TODO: repeater を "Go" で呼び出し、結果をプリントしてください
// TODO: これらを組み合わせます:repeater を "Dart" で呼び出した結果を
// 最初の wrapper に渡し、その結果をプリントしてください
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ13高度な OOP の概念
コンポジション vs 継承拡張メソッドCallable クラスSealed クラス (Dart 3)レコード (Dart 3)パターンとマッチング (3.0)メソッドを持つ Enum