← → or space · progress saves for Continue on the roadmap
Goal
Write code against a supertype so many subtypes can plug in without if/switch on concrete classes everywhere.
Step 1 - One list, many types
abstract class Notifier {
void send(String text);
}
class EmailNotifier implements Notifier {
@override
void send(String text) => print('email: $text');
}
class SmsNotifier implements Notifier {
@override
void send(String text) => print('sms: $text');
}
void notifyAll(List<Notifier> channels, String msg) {
for (final c in channels) {
c.send(msg);
}
}
void main() {
notifyAll([EmailNotifier(), SmsNotifier()], 'hello');
}channelsis typed asList<Notifier>; each element uses its ownsend.
Step 2 - Subtype substitution
- Where a
Notifieris expected, any class that satisfiesNotifieris allowed. - The caller depends on the abstraction, not concrete classes.
Good habit
- Push polymorphism to boundaries (services, repositories); keep leaf types small.
Practice tasks
- Add
PushNotifierand include it innotifyAllwithout changingnotifyAll’s body. - Replace the loop with
for (final c in channels) c.send(msg)using avoid Function(String)if you want to contrast object polymorphism with function values (optional).