Menu
Coddy logo textTech

Ключевое слово on в Mixins

Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 53 из 110.

Иногда примеси необходимо использовать методы или свойства класса, в который она включена. Ключевое слово on позволяет ограничить использование примеси только теми классами, которые расширяют определенный тип.

class Animal {
  String name;
  Animal(this.name);
  
  void breathe() => print('$name is breathing');
}

mixin Swimming on Animal {
  void swim() {
    print('$name is swimming');  // Можно получить доступ к 'name' из Animal
    breathe();  // Можно вызывать методы Animal
  }
}

class Fish extends Animal with Swimming {
  Fish(String name) : super(name);
}

Объявление on Animal означает, что этот миксин может быть применен только к классам, которые расширяют Animal. Это гарантирует, что миксин имеет доступ к членам Animal. Без on миксин не знал бы, что name или breathe() существуют.

Если вы попытаетесь использовать ограниченный mixin в несовместимом классе, Dart выдаст ошибку компиляции:

class Robot with Swimming {}  // Ошибка! Robot не наследует Animal

Это ограничение полезно, когда функциональность вашего миксина зависит от конкретных возможностей базового класса. Оно создает более безопасный контракт: миксин гарантирует определенное поведение, но только при наличии основы, необходимой для его корректной работы.

challenge icon

Задание

Легко

Давайте создадим систему транспортных средств, которая демонстрирует, как ключевое слово on ограничивает использование примесей (mixins) только конкретными базовыми классами. Вы создадите примесь, которая добавляет функциональность турбо-ускорения, но ее смогут использовать только те классы, которые расширяют базовый класс Vehicle.

Вы организуете свой код в двух файлах:

  • vehicles.dart: Определите здесь свой базовый класс, ограниченную примесь и типы транспортных средств:
    • Класс Vehicle со свойством String model и свойством int speed. Включите конструктор, принимающий оба значения. Добавьте метод accelerate(), который выводит '$model accelerating to $speed km/h'
    • Примесь TurboBoost, ограниченная классом Vehicle с помощью ключевого слова on. Эта примесь должна иметь метод activateTurbo(), который выводит '$model TURBO ACTIVATED!', а затем вызывает accelerate() (оба доступны благодаря ограничению on Vehicle)
    • Класс SportsCar, который расширяет Vehicle и использует примесь TurboBoost. Добавьте свойство String color. Конструктор должен принимать model, speed и color. Добавьте метод showOff(), который выводит '$color $model ready to race!'
  • main.dart: Импортируйте файл с транспортными средствами и продемонстрируйте работу ограниченной примеси:
    • Создайте объект SportsCar с моделью 'Ferrari', скоростью 320 и цветом 'Red'
    • Вызовите showOff()
    • Вызовите activateTurbo()

Примесь TurboBoost может обращаться к model и вызывать accelerate(), потому что объявление on Vehicle гарантирует, что она будет подмешиваться только в классы, расширяющие Vehicle. Это создает безопасный контракт, при котором примесь точно знает, какие возможности ей доступны.

Ожидаемый вывод:

Red Ferrari ready to race!
Ferrari TURBO ACTIVATED!
Ferrari accelerating to 320 km/h

Попробуйте сами

import 'vehicles.dart';

void main() {
  // TODO: Создайте SportsCar с моделью 'Ferrari', скоростью 320 и цветом 'Red'
  
  // TODO: Вызовите showOff()
  
  // TODO: Вызовите activateTurbo()
}
quiz iconПроверьте себя

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

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