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

Что такое sealed class?

2.0 Middle🔥 111 комментариев
#Dart#Архитектура Flutter#ООП и паттерны

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

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

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

Sealed класс в Dart

Sealed класс — это специальный тип класса, введённый в Dart 3.0, который позволяет создавать ограниченные иерархии наследования. Это гарантирует, что все подклассы известны на момент компиляции, что делает код более безопасным и типизированным.

Основное определение

sealed class Animal {}

Sealed класс:

  • Не может быть инстанцирован — нельзя создать объект Animal()
  • Может быть расширен только в том же файле — все подклассы должны быть известны
  • Позволяет exhaustive pattern matching — компилятор проверит все возможные случаи

Практические примеры

1. Иерархия типов (наследование в одном файле)

sealed class Animal {}

class Dog extends Animal {
  String breed;
  Dog(this.breed);
}

class Cat extends Animal {
  String color;
  Cat(this.color);
}

class Bird extends Animal {
  double wingSpan;
  Bird(this.wingSpan);
}

// ✅ Только подклассы
final dog = Dog('Labrador');
final cat = Cat('orange');

2. Exhaustive pattern matching

String getSound(Animal animal) {
  return switch (animal) {
    Dog() => 'Woof!',
    Cat() => 'Meow!',
    Bird() => 'Tweet!',
  };
}

final dog = Dog('Labrador');
print(getSound(dog)); // Woof!

3. Использование с switch выражениями

sealed class HttpResponse {}

class Success extends HttpResponse {
  final String data;
  Success(this.data);
}

class Error extends HttpResponse {
  final int statusCode;
  final String message;
  Error(this.statusCode, this.message);
}

class Loading extends HttpResponse {}

Widget buildResponseWidget(HttpResponse response) {
  return switch (response) {
    Success(data: var data) => Text('Success: $data'),
    Error(statusCode: var code, message: var msg) => Text('Error $code: $msg'),
    Loading() => const CircularProgressIndicator(),
  };
}

4. Результат операций (Result тип)

sealed class Result<T> {}

class Ok<T> extends Result<T> {
  final T value;
  Ok(this.value);
}

class Err<T> extends Result<T> {
  final Exception error;
  Err(this.error);
}

Result<String> divide(int a, int b) {
  if (b == 0) {
    return Err(Exception('Division by zero'));
  }
  return Ok('Result: ${a / b}');
}

final result = divide(10, 2);
final message = switch (result) {
  Ok(value: var value) => 'Success: $value',
  Err(error: var error) => 'Error: ${error.toString()}',
};

Сравнение с альтернативами

Sealed класс vs Abstract класс

// Abstract класс открыт для наследования откуда угодно
abstract class Base {
  void doSomething();
}

class CustomImpl extends Base {
  @override
  void doSomething() {}
}

// Sealed класс закрыт для наследования
sealed class Status {}
class Pending extends Status {}
class Complete extends Status {}

Sealed класс vs Enum

enum Color { red, green, blue } // Простые значения

sealed class Animal {} // Сложные иерархии
class Dog extends Animal {
  String breed;
  Dog(this.breed);
}

Преимущества sealed классов

Безопасность типов — компилятор гарантирует полноту switch ✅ Контроль наследования — все подклассы известны ✅ Чистота кода — нет неожиданных реализаций ✅ Рефакторинг — изменение иерархии вызовет ошибки компиляции ✅ Производительность — больше возможностей для оптимизации

Использование в Flutter

BLoC/Cubit состояния

sealed class CounterState {}

class CounterInitial extends CounterState {}
class CounterLoading extends CounterState {}
class CounterLoaded extends CounterState {
  final int count;
  CounterLoaded(this.count);
}
class CounterError extends CounterState {
  final String message;
  CounterError(this.message);
}

BlocBuilder<CounterBloc, CounterState>(
  builder: (context, state) {
    return switch (state) {
      CounterInitial() => const Text('Initial'),
      CounterLoading() => const CircularProgressIndicator(),
      CounterLoaded(count: var count) => Text('Count: $count'),
      CounterError(message: var msg) => Text('Error: $msg'),
    };
  },
)

Правила и ограничения

  • Sealed класс не может быть инстанцирован
  • Все подклассы должны быть в одном файле
  • Подклассы могут наследовать sealed класс или другой sealed класс
  • Sealed класс может быть абстрактным или конкретным

Заключение

Sealed классы — это мощный инструмент для создания безопасных иерархий типов. Они особенно полезны в State Management паттернах, где нужно обработать все возможные состояния приложения.