Что такое sealed class в Dart?

«Что такое sealed class в Dart?» — вопрос из категории Dart Core, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Sealed class (запечатанный класс) в Dart — это класс, который явно ограничивает своё наследование. Все его прямые подтипы должны быть объявлены в том же файле (и библиотеке), что и сам sealed class. Это создаёт замкнутую иерархию типов, известную компилятору, что позволяет использовать исчерпывающий (exhaustive) pattern matching.

Основная цель: Моделирование дискретных, известных на этапе компиляции вариантов, таких как состояния загрузки, результаты операций или узлы AST.

Пример: Моделирование результата сетевого запроса

// Все возможные подтипы Result определены здесь и только здесь.
sealed class Result<T> {}

class Success<T> extends Result<T> {
  final T data;
  Success(this.data);
}

class Error<T> extends Result<T> {
  final Exception exception;
  Error(this.exception);
}

class Loading<T> extends Result<T> {}

// Использование с исчерпывающим switch
Widget buildResultWidget(Result<String> result) {
  return switch (result) {
    Success(data: final data) => Text('Данные: $data'),
    Error(exception: final e) => Text('Ошибка: ${e.toString()}'),
    Loading() => CircularProgressIndicator(),
    // Компилятор знает, что все случаи покрыты. Если добавить новый подтип Result,
    // switch выдаст ошибку компиляции, пока его не обработать.
  };
}

Преимущества:

  • Безопасность: Компилятор гарантирует обработку всех вариантов в switch и if-case.
  • Читаемость: Структура данных явно документирована в коде.
  • Удобство рефакторинга: При добавлении нового варианта компилятор укажет все места, которые нужно обновить.