← Назад к вопросам

Чем отличаются extension, mixin и abstract class в Dart?

1.7 Middle🔥 152 комментариев
#Dart#ООП и паттерны

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Extension, Mixin и Abstract Class в Dart

Это три разных механизма для переиспользования кода и расширения функционала, но с разными сценариями применения и правилами использования.

Abstract Class — контракт и базовая логика

Абстрактный класс — это шаблон для наследования, который не может быть инстанцирован напрямую. Используется для:

  • Определения интерфейса (контракта)
  • Предоставления общей логики для подклассов
  • Создания иерархии типов
abstract class Animal {
  String get name; // абстрактное свойство
  
  void eat() { // конкретная реализация
    print($name eating);
  }
  
  void sound(); // абстрактный метод
}

class Dog extends Animal {
  @override
  String get name => Dog;
  
  @override
  void sound() => print(Woof!);
}

Особенности:

  • Наследование (extends) — класс может наследовать только от одного класса
  • Может иметь состояние (поля) и конструкторы
  • Может иметь приватные методы и переменные
  • Используется для создания иерархии типов

Mixin — переиспользуемое поведение без иерархии

Mixin — это набор методов и свойств, которые можно добавить к любому классу. Использует with вместо наследования.

mixin Flyer {
  void fly() => print(Flying...);
  int get altitude => 1000;
}

mixin Swimmer {
  void swim() => print(Swimming...);
}

class Duck with Flyer, Swimmer {
  String name = Duck;
}

final duck = Duck();
duck.fly(); // Flying...
duck.swim(); // Swimming...

Особенности:

  • Может применяться к любому классу через with
  • Можно применять несколько миксинов одновременно
  • Может иметь свойства и методы
  • Не может иметь конструктор (или очень ограниченно в Dart 2.1+)
  • Решает проблему множественного наследования (composition over inheritance)

Extension — расширение функционала существующих типов

Extension — это способ добавить методы/свойства к существующему классу без изменения его исходного кода и без наследования.

extension StringExtension on String {
  String get capitalized => this[0].toUpperCase() + substring(1);
  
  bool get isEmail => contains(@) && contains(.);
  
  String reverse() => split().reversed.join();
}

final text = hello world;
print(text.capitalized); // Hello world
print(test@example.com.isEmail); // true
print(text.reverse()); // dlrow olleh

Особенности:

  • Работает как синтаксический сахар (compile-time)
  • Не может переопределять существующие методы
  • Видны только где импортированы
  • Идеален для утилит и вспомогательных методов
  • Может применяться к встроенным типам (String, List, int и т.д.)

Сравнительная таблица

АспектAbstract ClassMixinExtension
НаследованиеИерархия типовГоризонтальное переиспользованиеНет иерархии
КоличествоОдин суперклассНесколько миксиновНесколько расширений
СостояниеДа (поля)Да (поля)Нет
КонструкторДаНет (или с ограничениями)Нет
ВидимостьНа уровне классаНа уровне классаНа уровне импорта
Переопределение методовДаДаНет
ИспользованиеКонтракт и иерархияПоведение и способностиУтилиты и вспомогательные методы

Когда использовать что?

Abstract Class:

  • Нужна иерархия типов (Animal → Dog, Cat)
  • Требуется общее состояние (конструктор, поля)
  • Контролируешь код класса

Mixin:

  • Нужно добавить поведение без иерархии
  • Одно поведение может применяться к разным классам
  • Избегаешь проблемы множественного наследования

Extension:

  • Нужно расширить чужой класс (из библиотеки)
  • Хочешь добавить утилиты (например, методы на String или DateTime)
  • Не хочешь менять структуру типов

Вывод: Abstract class для иерархии, mixin для способностей и поведения, extension для утилит и расширения существующих типов.

Чем отличаются extension, mixin и abstract class в Dart? | PrepBro