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
Classes and Constructors
Define classes with named and factory constructors.
Async/Await and Futures
Asynchronous programming with Future and async/await.
Collections (List, Map, Set)
Work with collections and functional operations.
Null Safety
Sound null safety with ? and ! operators.
Generics
Type-safe reusable classes and methods.
Futures and Streams
Work with single and multiple async values.