Question #116EasyGeneral

What is 𝗦𝗲𝗮𝗹𝗲𝗱 𝗖𝗹𝗮𝘀𝘀𝗲𝘀 & 𝗣𝗮𝘁𝘁𝗲𝗿𝗻 𝗠𝗮𝘁𝗰𝗵𝗶𝗻𝗴 𝗶𝗻 𝗗𝗮𝗿𝘁 ?

Answer

Overview

Sealed classes in Dart 3+ are classes that restrict which classes can extend or implement them — all subclasses must be defined in the same file/library. Combined with pattern matching, they enable exhaustive

text
switch
expressions.


Sealed Classes (Dart 3+)

dart
// Sealed class — all subclasses must be in the same file
sealed class Shape {}

class Circle extends Shape {
  final double radius;
  Circle(this.radius);
}

class Rectangle extends Shape {
  final double width, height;
  Rectangle(this.width, this.height);
}

class Triangle extends Shape {
  final double base, height;
  Triangle(this.base, this.height);
}

Pattern Matching with switch

dart
double calculateArea(Shape shape) {
  // Exhaustive switch — compiler enforces all cases handled
  return switch (shape) {
    Circle(radius: final r) => 3.14159 * r * r,
    Rectangle(width: final w, height: final h) => w * h,
    Triangle(base: final b, height: final h) => 0.5 * b * h,
    // No default needed — compiler knows all cases!
  };
}

void main() {
  print(calculateArea(Circle(5)));        // 78.54
  print(calculateArea(Rectangle(4, 6))); // 24.0
}

Sealed Classes for API States (BLoC / Riverpod)

dart
sealed class ApiState<T> {}

class ApiLoading<T> extends ApiState<T> {}

class ApiSuccess<T> extends ApiState<T> {
  final T data;
  ApiSuccess(this.data);
}

class ApiError<T> extends ApiState<T> {
  final String message;
  ApiError(this.message);
}

// In widget — exhaustive + type-safe
Widget buildContent(ApiState<List<User>> state) {
  return switch (state) {
    ApiLoading() => CircularProgressIndicator(),
    ApiSuccess(data: final users) => UserList(users),
    ApiError(message: final msg) => ErrorText(msg),
  };
}

Other Dart 3 Pattern Types

dart
// Object pattern
final point = (x: 3, y: 4);
final (x: px, y: py) = point; // Destructuring

// List pattern
final [first, second, ...rest] = [1, 2, 3, 4, 5];
print(first); // 1
print(rest);  // [3, 4, 5]

// Map pattern
final {'name': name, 'age': age} = {'name': 'Alice', 'age': 28};

// Guard clause (when)
switch (value) {
  case int n when n > 0 => print('Positive'),
  case int n when n < 0 => print('Negative'),
  case 0 => print('Zero'),
}

Sealed vs Abstract vs Enum

Feature
text
sealed
text
abstract
text
enum
Subclasses restricted to file✅ Yes❌ No
Exhaustive switch✅ Yes❌ No✅ Yes
Can have fields✅ Yes✅ YesLimited
Pattern matching✅ Full supportPartialPartial

Key Benefit: Sealed classes + pattern matching replace verbose

text
if/else instanceof
chains with compile-verified, exhaustive switch expressions — no more missed cases at runtime.