Создание Mixins
Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 51 из 110.
Теперь, когда вы понимаете, что такое миксины, давайте посмотрим, как их правильно создавать. Миксин объявляется с использованием ключевого слова mixin вместо class.
mixin Logging {
void log(String message) {
print('[LOG] $message');
}
void logError(String error) {
print('[ERROR] $error');
}
}Миксины могут содержать методы, свойства и даже геттеры и сеттеры — точно так же, как и классы. Однако есть одно важное правило: миксины не могут иметь конструкторов. Поскольку миксины предназначены для «подмешивания», а не для прямого создания экземпляров, им не требуется логика инициализации.
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(); // Использует метод миксина
print(doc.createdAt); // Использует свойство миксина
}Когда вы применяете миксин с помощью with, все его члены становятся частью вашего класса. Класс может использовать их напрямую, как и любой код, имеющий экземпляр этого класса. Это делает миксины удобным способом добавления повторно используемой функциональности без усложнения иерархии наследования.
Задание
ЛегкоДавайте создадим систему обмена сообщениями, которая демонстрирует, как создавать примеси (mixins) с методами, свойствами и геттерами. Вы разработаете примесь, которая добавляет возможности форматирования различным типам сообщений.
Вы организуете свой код в двух файлах:
messaging.dart: Определите здесь вашу примесь и классы сообщений:- Примесь
Formattable, которая содержит:- Свойство
String prefix, инициализированное значением'>>>' - Геттер
separator, который возвращает' | ' - Метод
format(String text), который возвращает строку[prefix][separator][text] - Метод
formatBold(String text), который возвращает**[text]**
- Свойство
- Класс
TextMessage, использующий примесьFormattable. Добавьте свойствоString senderс конструктором. Включите методsend(String content), который выводит результат вызоваformat()с аргументом[sender]: [content] - Класс
AlertMessage, также использующий примесьFormattable. Добавьте свойствоString levelс конструктором. Включите методalert(String content), который выводит результат вызоваformat()с аргументом[[level]] [formatBold(content)]
- Примесь
main.dart: Импортируйте ваш файл обмена сообщениями и продемонстрируйте, как оба типа сообщений получают возможности форматирования из примеси:- Создайте
TextMessageс отправителем'Alice' - Создайте
AlertMessageс уровнем'WARNING' - Вызовите
send('Hello there!')у текстового сообщения - Вызовите
alert('System overload')у сообщения с предупреждением
- Создайте
Ваша примесь демонстрирует, что примеси могут содержать свойства со значениями по умолчанию, геттеры, вычисляющие значения, и несколько методов, которые могут даже вызывать друг друга. Оба класса сообщений получают всю эту функциональность, просто используя ключевое слово with.
Ожидаемый вывод:
>>> | Alice: Hello there!
>>> | [WARNING] **System overload**Шпаргалка
Миксины объявляются с помощью ключевого слова mixin вместо class:
mixin Logging {
void log(String message) {
print('[LOG] $message');
}
void logError(String error) {
print('[ERROR] $error');
}
}Миксины могут содержать методы, свойства, геттеры и сеттеры, но не могут иметь конструкторов:
mixin Timestamped {
DateTime createdAt = DateTime.now();
String get formattedTime => createdAt.toString();
void printTimestamp() {
print('Created at: $formattedTime');
}
}Применяйте миксины к классам с помощью ключевого слова with. Все члены миксина становятся частью класса:
class Document with Timestamped {
String title;
Document(this.title);
}
void main() {
var doc = Document('Report');
doc.printTimestamp(); // Использует метод миксина
print(doc.createdAt); // Использует свойство миксина
}Попробуйте сами
import 'messaging.dart';
void main() {
// TODO: Создайте TextMessage с отправителем 'Alice'
// TODO: Создайте AlertMessage с уровнем 'WARNING'
// TODO: Вызовите send('Hello there!') для текстового сообщения
// TODO: Вызовите alert('System overload') для сообщения с предупреждением
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий