Menu
Coddy logo textTech

Создание 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, все его члены становятся частью вашего класса. Класс может использовать их напрямую, как и любой код, имеющий экземпляр этого класса. Это делает миксины удобным способом добавления повторно используемой функциональности без усложнения иерархии наследования.

challenge icon

Задание

Легко

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

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

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