Menu
Coddy logo textTech

ジェネリッククラス

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

Dart の組み込みコレクションである List<String> が型パラメーターを使用する方法を見てきました。次は、指定した任意の型で動作する独自のジェネリッククラスを作成しましょう。

generic クラスは、インスタンスを作成するときに指定される実際の型のプレースホルダーとして、型パラメーター(通常は T)を使用します。

class Box<T> {
  T content;
  
  Box(this.content);
  
  T getContent() => content;
}

void main() {
  var stringBox = Box<String>('Hello');
  var intBox = Box<int>(42);
  
  print(stringBox.getContent());  // Hello
  print(intBox.getContent());     // 42
}

Tは型変数として機能します。Box<String>を作成すると、クラス内のすべてのTStringになります。これにより、型ごとに個別のクラスを記述しなくても型安全性を確保できます。

クラスが複数の型を扱う必要がある場合は、複数の型パラメーターを使用できます。

class Pair<K, V> {
  K first;
  V second;
  
  Pair(this.first, this.second);
}

void main() {
  var pair = Pair<String, int>('age', 25);
  print('${pair.first}: ${pair.second}');  // age: 25
}

ジェネリッククラスは、再利用可能で型安全なコードの基盤です。異なる型ごとにロジックを複製したり、dynamic によって型情報を失ったりする代わりに、ジェネリックを使えば、コンパイラが検証できる柔軟なコードを記述できます。

challenge icon

チャレンジ

簡単

generic class を使用して、さまざまな種類のアイテム用に柔軟なコンテナを作成するギフト包装システムを構築しましょう。あらゆる種類の content を包める generic Wrapper class と、gift と card message を組み合わせるための2つの type parameter を持つ GiftBox class を Create します。

コードを2つのファイルに整理します。

  • wrapper.dart:ここで generic classes を Define します。
    • Wrapper<T> という generic class。T content property と Constructor を持たせます。content を returns する unwrap() Method と、Wrapped: [content] を Print する describe() Method を含めます。
    • GiftBox<G, C> という generic class。2つの Properties、G giftC card を持たせます。Constructor と、1行目に Gift: [gift]、次の行に Card: [card] を Print する open() Method を含めます。
  • main.dart:wrapper file を import し、異なる types で generic classes を実演します。
    • Wrapper<String>'Chocolate' containing の状態で Create し、describe() を call します。
    • Wrapper<int>42 containing の状態で Create し、describe() を call します。
    • Wrapper<double>3.14 containing の状態で Create し、describe() を call します。
    • empty line を Print します。
    • gift 'Teddy Bear' と card 'Happy Birthday!' を持つ GiftBox<String, String> を Create し、その後 open() を call します。
    • empty line を Print します。
    • gift 100(gift card の金額を表します)と card 'Congratulations!' を持つ GiftBox<int, String> を Create し、その後 open() を call します。

同じ Wrapper class が strings、integers、doubles でシームレスに動作することに注目してください。GiftBox class は、2つの type parameters を使用して異なる types を pair にする方法を示しています。gift は任意の type にできますが、card message は string のままです。

Expected output:

Wrapped: Chocolate
Wrapped: 42
Wrapped: 3.14

Gift: Teddy Bear
Card: Happy Birthday!

Gift: 100
Card: Congratulations!

自分で試してみよう

import 'wrapper.dart';

void main() {
  // TODO: 'Chocolate' を含む Wrapper<String> を作成し、describe() を呼び出す
  
  // TODO: 42 を含む Wrapper<int> を作成し、describe() を呼び出す
  
  // TODO: 3.14 を含む Wrapper<double> を作成し、describe() を呼び出す
  
  // TODO: 空行を出力する
  
  // TODO: Create a GiftBox<String, String> with gift 'Teddy Bear' 
  // and card 'Happy Birthday!', then call open()
  
  // TODO: 空行を出力する
  
  // TODO: gift 100 の GiftBox<int, String> を作成する 
  // and card 'Congratulations!', then call open()
}
quiz icon腕試し

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

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

自分で練習してみよう: Dartオンラインコンパイラ