Ответ
Ключевое слово abstract, официально представленное в Dart 2.12 вместе с null safety, не было "новым" в полном смысле. Оно стало обязательным для объявления абстрактных классов. Это изменение усилило выразительность системы типов и сделало дизайн кода более явным и безопасным.
Раньше (до Dart 2.12): Абстрактный класс можно было объявить просто добавив в него абстрактный метод. Это было неявно и могло вводить в заблуждение.
// Старый стиль (неявная абстрактность)
class Animal {
void makeSound(); // Наличие абстрактного метода делало класс абстрактным
void sleep() => print('Sleeping');
}
// var a = Animal(); // Runtime error: Cannot instantiate abstract class.
Теперь (Dart 2.12+):
Модификатор abstract требуется явно. Это сразу сообщает и разработчику, и инструментам (анализатору, IDE), что класс является контрактом и не может быть инстанциирован.
// Новый стиль (явная абстрактность)
abstract class Animal {
void makeSound(); // Абстрактный метод
void sleep() => print('Sleeping'); // Реализованный метод
}
class Dog extends Animal {
@override
void makeSound() => print('Woof!');
}
// var a = Animal(); // ОШИБКА КОМПИЛЯЦИИ: Abstract classes can't be instantiated.
var d = Dog(); // OK
Практическая польза в Flutter:
- Чёткое разделение ответственности: Позволяет создавать чистые интерфейсы (контракты) для репозиториев, сервисов, use-cases, что является основой для тестируемой архитектуры (например, с Clean Architecture).
- Улучшенная поддержка инструментов: IDE может сразу показывать, какие классы нужно реализовать, а какие — нет.
- Безопасность: Ошибка попытки создания экземпляра абстрактного класса теперь ловится на этапе компиляции, а не во время выполнения. Это напрямую связано с философией null safety — перемещать ошибки из runtime в compile-time.