Обобщенные методы
Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy. Урок 66 из 110.
Как и классы, отдельные методы тоже могут иметь собственные параметры типа. Это полезно, когда нужен гибкий метод, но делать весь класс обобщённым не требуется.
Обобщённый метод объявляет параметр типа перед типом возвращаемого значения:
T findFirst<T>(List<T> items) {
return items.first;
}
void main() {
var firstNumber = findFirst<int>([1, 2, 3]);
var firstWord = findFirst<String>(['hello', 'world']);
print(firstNumber); // 1
print(firstWord); // привет
}Dart часто может определить тип по аргументам, поэтому не всегда нужно указывать его явно:
var result = findFirst([10, 20, 30]); // Dart выводит тип intОбобщённые методы особенно полезны внутри классов, когда гибкость типов требуется лишь для некоторых операций:
class Printer {
void printItem<T>(T item) {
print('Printing: $item');
}
List<T> duplicate<T>(T item, int count) {
return List.filled(count, item);
}
}
void main() {
var printer = Printer();
printer.printItem<String>('Hello');
printer.printItem(42); // Тип определён как int
var copies = printer.duplicate('Hi', 3);
print(copies); // [Hi, Hi, Hi]
}Обобщённые методы позволяют точно контролировать безопасность типов на уровне методов, сохраняя классы более простыми и пользуясь при этом проверкой типов во время компиляции.
Задание
ЛегкоДавайте создадим утилиту преобразования данных, которая продемонстрирует возможности обобщённых методов. Вы создадите класс Transformer с методами, которые могут работать с любым типом, обеспечивая гибкость без необходимости делать весь класс обобщённым.
Вы организуете код в двух файлах:
transformer.dart: создайте классTransformerсо следующими обобщёнными методами:T getFirst<T>(List<T> items)— возвращает первый элемент спискаT getLast<T>(List<T> items)— возвращает последний элемент спискаList<T> repeat<T>(T item, int times)— создаёт список, содержащий указанное количество повторений элементаvoid printPair<A, B>(A first, B second)— выводит два значения в форматеPair: [first] and [second]
main.dart: импортируйте файл с преобразователем и продемонстрируйте каждый обобщённый метод с разными типами:- Создайте экземпляр
Transformer - Примените
getFirstк[10, 20, 30]и выведите результат - Примените
getFirstк['apple', 'banana', 'cherry']и выведите результат - Примените
getLastк[1.5, 2.5, 3.5]и выведите результат - Используйте
repeat, чтобы создать список из'Hi', повторённого4раза, и выведите результат - Используйте
repeat, чтобы создать список из7, повторённого3раза, и выведите результат - Используйте
printPairсо значениями'Name'и42 - Используйте
printPairсо значениями100иtrue
- Создайте экземпляр
Обратите внимание, что каждый метод объявляет собственные параметры типа, поэтому один и тот же объект Transformer может работать с целыми числами, строками, числами с плавающей точкой и логическими значениями — при этом типобезопасность полностью сохраняется. Метод printPair демонстрирует использование двух параметров типа в одном методе.
Ожидаемый результат:
10
apple
3.5
[Hi, Hi, Hi, Hi]
[7, 7, 7]
Pair: Name and 42
Pair: 100 and trueПопробуйте сами
import 'transformer.dart';
void main() {
// Создайте экземпляр Transformer
var transformer = Transformer();
// TODO: Примените getFirst к [10, 20, 30] и выведите результат
// TODO: Примените getFirst к ['apple', 'banana', 'cherry'] и выведите результат
// TODO: Примените getLast к [1.5, 2.5, 3.5] и выведите результат
// TODO: Используйте repeat, чтобы создать список, содержащий 'Hi' 4 раза, и выведите его
// TODO: Используйте repeat, чтобы создать список, содержащий 7 3 раза, и выведите его
// TODO: Вызовите printPair с аргументами 'Name' и 42
// TODO: Вызовите printPair с аргументами 100 и true
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыБиблиотеки и импортВведение в ООПКлассы и объектыКлючевое слово thisМетодыПеременные экземпляраОсновы конструкторовИтоги — Простой калькулятор4Null-безопасность
Введение в Null-безопасностьNullable и Non-Nullable типыОператоры ? и !Ключевое слово Late и Null-безопасностьNull-aware операторыNull-безопасность в классахИтоги — Система профилей пользователей7Абстрактные классы и интерфейсы
Абстрактные классыАбстрактные методыИнтерфейсы в DartНеявные интерфейсыРеализация против наследованияМножественные интерфейсыИтоги — Калькулятор фигур10Коллекции и обобщения
Обзор List, Set, MapТипобезопасные коллекцииОбобщенные классыОбобщенные методыОграничения обобщенийIterable и IteratorИтоги: Обобщенное хранилище13Продвинутые концепции ООП
Композиция против наследованияМетоды расширенияВызываемые классыЗапечатанные классы (Dart 3)Записи (Dart 3)Паттерны и сопоставление (3.0)Перечисления с методами16Проект: Управление библиотекой
Обзор проектаКлассы Book и User2Конструкторы в Dart
Конструктор по умолчаниюИменованные конструкторыСписки инициализацииКонстантные конструкторыФабричные конструкторыПеренаправляющие конструкторыИтоги — Shape Builder5Инкапсуляция
Публичные и приватные членыСоглашение о префиксе _Приватность на уровне библиотекГеттеры и сеттеры: подробный разборСкрытие данныхИтоги — Записи о студентах8Mixins
Введение в MixinsСоздание MixinsИспользование нескольких MixinsКлючевое слово on в MixinsMixin и наследованиеMixin и интерфейсИтоги: Система животных11Специальные методы
Переопределение toString()Переопределение hashCode и ==Интерфейс ComparableМетод call()Переопределение noSuchMethodПовторение — Пользовательская коллекция14Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy3Свойства классов
Члены экземпляра и статические членыПоля Final и ConstПеременные LateСтатические методы и поляГеттеры и сеттерыИтоги — Менеджер банковского счета6Наследование
Основы наследованияКлючевое слово superПереопределение методовАннотация @overrideКлючевое слово final для классовКонструкторы и наследованиеИтоги: Иерархия сотрудников9Полиморфизм
Основы полиморфизмаПолиморфизм через интерфейсыПроверка типов во время выполненияОператоры is и asКлючевое слово covariantИтоги — Обработчик платежей12Асинхронное ООП
Futures и async/awaitОсновы StreamsКонтроллеры StreamАсинхронные конструкторыАсинхронность в методах классовИтоги — Data Fetcher15Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн РепозиторийПотренируйтесь самостоятельно: Онлайн-компилятор Dart