Skip to content
Dart

Mixins and Extensions

Compose behaviors without inheritance.

By EZ4Code Team
mixinextensioncomposition

Code

// Mixin: reusable behavior
mixin Logging {
  void log(String msg) => print('[LOG] $msg');
}

mixin Timestamped {
  DateTime get createdAt => DateTime.now();
}

class Service with Logging, Timestamped {
  void run() {
    log('Started at $createdAt');
  }
}

// Mixin with constraint (on)
mixin SortedList<T extends Comparable<T>> on List<T> {
  void sortedAdd(T item) {
    add(item);
    sort();
  }
}

// Extension: add methods to existing types
extension StringX on String {
  String capitalize() =>
      isEmpty ? this : '${this[0].toUpperCase()}${substring(1)}';

  bool get isEmail => contains('@') && contains('.');
}

// Extension on nullable
extension NullableStringX on String? {
  bool get isNullOrEmpty => this == null || this!.isEmpty;
}

void main() {
  final s = Service()..run();
  print('hello'.capitalize());  // Hello
  print('[email protected]'.isEmail);     // true
  String? maybe;
  print(maybe.isNullOrEmpty);   // true
}

Explanation

Mixins add behavior to classes without inheritance — `with` mixes them in. `on` constrains a mixin to a specific supertype. Extensions add methods to existing types (even built-ins) without subclassing — useful for utility functions. Extensions on nullable types provide safe helpers. Both are key to Dart's composability.

More Dart Snippets