Использование нескольких Mixins
Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 52 из 110.
Точно так же, как вы можете реализовывать несколько интерфейсов, вы также можете применять несколько миксинов к одному классу. Просто перечислите их после ключевого слова with через запятую.
mixin Swimming {
void swim() => print('Swimming');
}
mixin Flying {
void fly() => print('Flying');
}
mixin Walking {
void walk() => print('Walking');
}
class Duck with Swimming, Flying, Walking {
void quack() => print('Quack!');
}
void main() {
var duck = Duck();
duck.swim(); // Из миксина Swimming
duck.fly(); // Из миксина Flying
duck.walk(); // Из миксина Walking
duck.quack(); // Из класса Duck
}Порядок примесей имеет значение, когда они содержат методы с одинаковыми именами. Последняя примесь в списке имеет приоритет:
mixin A {
void greet() => print('Hello from A');
}
mixin B {
void greet() => print('Hello from B');
}
class MyClass with A, B {}
void main() {
MyClass().greet(); // Вывод: Hello from B
}Так как B идет после A, его метод greet() имеет приоритет. Такое поведение наслоения позволяет составлять классы именно с теми возможностями, которые вам нужны, объединяя функциональность из нескольких источников без сложных иерархий наследования.
Задание
ЛегкоДавайте создадим систему устройств для умного дома, которая объединяет несколько возможностей с помощью примесей (mixins). Вы создадите различные примеси, представляющие разнообразные интеллектуальные функции, а затем создадите устройство, которое использует их все вместе.
Вы организуете свой код в два файла:
smart_features.dart: Определите три примеси, которые предоставляют различные возможности умного дома:- Примесь
VoiceControlс методомvoiceCommand(String command), который выводитVoice: [command] - Примесь
WiFiEnabledс методомconnectWiFi(String network), который выводитConnected to [network] - Примесь
PowerSaverс методомenterSleepMode(), который выводитEntering sleep mode..., и методомwakeUp(), который выводитWaking up!
SmartSpeaker, который использует все три примеси. Добавьте свойствоString nameс конструктором и включите методplayMusic(String song), который выводит[name] playing: [song]- Примесь
main.dart: Импортируйте файл с функциями умного дома и продемонстрируйте, как колонка объединяет все возможности:- Создайте
SmartSpeakerс именем'Echo' - Вызовите
connectWiFi('HomeNetwork') - Вызовите
voiceCommand('Play jazz') - Вызовите
playMusic('Smooth Jazz Mix') - Вызовите
enterSleepMode() - Вызовите
wakeUp()
- Создайте
Ваш SmartSpeaker получает методы из всех трех примесей с помощью одного предложения with, демонстрируя, как несколько примесей позволяют вам компоновать именно те возможности, которые вам нужны, без сложного наследования.
Ожидаемый результат:
Connected to HomeNetwork
Voice: Play jazz
Echo playing: Smooth Jazz Mix
Entering sleep mode...
Waking up!Шпаргалка
Класс может применять несколько примесей (mixins), перечисляя их после ключевого слова with через запятую:
mixin Swimming {
void swim() => print('Swimming');
}
mixin Flying {
void fly() => print('Flying');
}
class Duck with Swimming, Flying {
void quack() => print('Quack!');
}
void main() {
var duck = Duck();
duck.swim(); // Из примеси Swimming
duck.fly(); // Из примеси Flying
duck.quack(); // Из класса Duck
}Когда несколько примесей имеют методы с одинаковым именем, приоритет имеет последняя примесь в списке:
mixin A {
void greet() => print('Hello from A');
}
mixin B {
void greet() => print('Hello from B');
}
class MyClass with A, B {}
void main() {
MyClass().greet(); // Вывод: Hello from B
}Попробуйте сами
import 'smart_features.dart';
void main() {
// TODO: Создайте SmartSpeaker с именем 'Echo'
// TODO: Вызовите connectWiFi('HomeNetwork')
// TODO: Вызовите voiceCommand('Play jazz')
// TODO: Вызовите playMusic('Smooth Jazz Mix')
// TODO: Вызовите enterSleepMode()
// TODO: Вызовите wakeUp()
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий