Menu
Coddy logo textTech

Использование нескольких 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() имеет приоритет. Такое поведение наслоения позволяет составлять классы именно с теми возможностями, которые вам нужны, объединяя функциональность из нескольких источников без сложных иерархий наследования.

challenge icon

Задание

Легко

Давайте создадим систему устройств для умного дома, которая объединяет несколько возможностей с помощью примесей (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()
}
quiz iconПроверьте себя

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

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