Menu
Coddy logo textTech

Обобщенные классы

Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy. Урок 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>, каждый T в классе становится String. Это обеспечивает безопасность типов без необходимости писать отдельные классы для каждого типа.

Вы можете использовать несколько параметров типа, когда вашему классу нужно работать более чем с одним типом:

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
}

Классы generic — основа повторно используемого и типобезопасного кода. Вместо дублирования логики для разных типов или потери информации о типах при использовании dynamic generics позволяют писать гибкий код, который компилятор всё ещё может проверять.

challenge icon

Задание

Легко

Давайте создадим систему упаковки подарков, которая использует generic классы для создания гибких контейнеров для разных типов элементов. Вы создадите generic класс Wrapper, который может оборачивать любой тип content, и класс GiftBox с двумя параметрами типа для объединения подарка с сообщением на открытке.

Вы организуете код в два файла:

  • wrapper.dart: Define здесь ваши generic классы:
    • generic класс Wrapper<T> со свойством T content и Constructor. Добавьте Method unwrap(), который returns content, и Method describe(), который выводит Wrapped: [content]
    • generic класс GiftBox<G, C> с двумя свойствами: G gift и C card. Добавьте Constructor и Method open(), который выводит Gift: [gift] в одной строке и Card: [card] в следующей строке
  • main.dart: импортируйте файл wrapper и продемонстрируйте generic классы с разными типами:
    • Create Wrapper<String>, содержащий 'Chocolate', и call describe()
    • Create Wrapper<int>, содержащий 42, и call describe()
    • Create Wrapper<double>, содержащий 3.14, и call describe()
    • Выведите пустую строку
    • Create GiftBox<String, String> с gift 'Teddy Bear' и card 'Happy Birthday!', затем call open()
    • Выведите пустую строку
    • Create GiftBox<int, String> с gift 100 (представляющим сумму подарочной карты) и card 'Congratulations!', затем call open()

Обратите внимание, как один и тот же класс Wrapper без проблем работает со строками, целыми числами и числами double. Класс GiftBox демонстрирует использование двух параметров типа для объединения разных типов: gift может иметь любой тип, а сообщение на card остаётся строкой.

Ожидаемый результат:

Wrapped: Chocolate
Wrapped: 42
Wrapped: 3.14

Gift: Teddy Bear
Card: Happy Birthday!

Gift: 100
Card: Congratulations!

Попробуйте сами

import 'wrapper.dart';

void main() {
  // TODO: Создайте Wrapper<String>, содержащий 'Chocolate', и вызовите describe()
  
  // TODO: Создайте Wrapper<int>, содержащий 42, и вызовите describe()
  
  // TODO: Создайте Wrapper<double>, содержащий 3.14, и вызовите describe()
  
  // TODO: Выведите пустую строку
  
  // TODO: Create a GiftBox<String, String> with gift 'Teddy Bear' 
  // and card 'Happy Birthday!', then call open()
  
  // TODO: Выведите пустую строку
  
  // TODO: Создайте GiftBox<int, String> с подарком 100 
  // and card 'Congratulations!', then call open()
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Dart