Beginner · Null safety and object-oriented Dart · topic 7 of 50 · 30 min
Inheritance, interfaces, mixins and extensions
Explanation
Inheritance with extends
Inheritance lets a subclass reuse a parent class and change only what differs. In Flutter, your screens extend StatelessWidget or StatefulWidget and override build. A class can extend only one class.
class Ticket {
final String passenger;
final int baseFare;
Ticket(this.passenger, this.baseFare);
int total() => baseFare;
String summary() => '$passenger: Rs ${total()}';
}
class TrainTicket extends Ticket {
final bool tatkal;
TrainTicket(super.passenger, super.baseFare, {this.tatkal = false});
@override
int total() => tatkal ? baseFare + 300 : baseFare;
}
void main() {
final List<Ticket> all = [Ticket('Asha', 500), TrainTicket('Ravi', 1200, tatkal: true)];
for (final t in all) print(t.summary()); // Asha: Rs 500, Ravi: Rs 1500
}The List<Ticket> holds both kinds of ticket. When the loop calls summary(), each object uses its own version of total(). This is polymorphism: one call, different behaviour depending on the actual object.
Abstract classes
abstract class Shape {
double area(); // no body: subclasses must implement
String describe() => 'Area: ${area().toStringAsFixed(2)}';
}
class Circle extends Shape {
final double r;
Circle(this.r);
@override
double area() => 3.14159 * r * r;
}Implicit interfaces: implements
In Dart, every class also defines an interface: the list of its public members. Another class can promise to provide all of them with implements, without inheriting any code. This is how you create fakes for testing: class FakePaymentService implements PaymentService.
abstract class PaymentService {
Future<bool> pay(int paise);
}
class UpiPaymentService implements PaymentService {
@override
Future<bool> pay(int paise) async => true; // would call a real gateway
}
class FakePaymentService implements PaymentService {
@override
Future<bool> pay(int paise) async => paise < 1000000; // predictable for tests
}Mixins: sharing behaviour
A mixin is a bundle of methods and fields that can be added to several unrelated classes with the with keyword. A class can use many mixins. Flutter uses mixins for things like SingleTickerProviderStateMixin in animations (module 9).
mixin Loggable {
void log(String message) => print('[${runtimeType}] $message');
}
class OrderService with Loggable {
void place() => log('Order placed');
}
class CartService with Loggable {
void clear() => log('Cart cleared');
}Extension methods
An extension adds methods or getters to an existing type, even one you did not write, such as String or int. It does not change the class; it is resolved at compile time from the static type.
extension IndianFormat on int {
String get rupees => 'Rs $this';
}
extension Initials on String {
String get initials => split(' ').where((w) => w.isNotEmpty).map((w) => w[0].toUpperCase()).join();
}
void main() {
print(499.rupees); // Rs 499
print('rahul kumar'.initials); // RK
}| Tool | Relationship | Use for |
|---|---|---|
| extends | is a (one parent) | Specialising a base class, Flutter widgets |
| implements | can do (promise all members) | Swappable services, fakes for tests |
| with (mixin) | has the ability | Sharing behaviour across unrelated classes |
| extension | adds to an existing type | Helpers on String, int, BuildContext |
Common mistakes
- Forgetting @override: allowed but discouraged; the annotation catches typos in method names.
- Deep inheritance trees for code reuse. Prefer composition, mixins or small helper classes.
- Using implements and expecting to inherit code: you must implement every member yourself.
- Forgetting to import the file that defines an extension: "The getter isn't defined".
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Inheritance, interfaces, mixins and extensions · 1/6
class TrainTicket extends Ticket {
@override
int total() => baseFare + 300;
}extends creates a subclass. Override changes a method. super calls the parent.
Prefer a video by a teacher? Find free videos on “dart inheritance abstract class implements mixin extension methods” on YouTube ↗
In real life: Swappable SMS providers
A clinic appointment app sends reminders by SMS. An abstract SmsSender defines send(phone, text). One class implements it with the clinic's SMS gateway, another with a fake used in tests and demos. A Loggable mixin adds logging to both, and an extension on String formats Indian phone numbers. Changing gateways later touches one class only.
abstract class SmsSender { Future<void> send(String phone, String text); }
mixin Loggable { void log(String m) => print('LOG: $m'); }
class FakeSmsSender with Loggable implements SmsSender {
@override
Future<void> send(String phone, String text) async => log('to $phone: $text');
}
extension PhoneFormat on String {
String get e164 {
final digits = replaceAll(RegExp(r'\D'), '');
return '+91${digits.length > 10 ? digits.substring(digits.length - 10) : digits}';
}
}Practice (0/3 done)
What does this print? class A { String hi() => 'A'; } class B extends A { @override String hi() => 'B' + super.hi(); } void main() { A x = B(); print(x.hi()); }
You need a fake of ApiClient for tests without inheriting its real network code. Which keyword?
Create an abstract class Discount with int apply(int price). Implement FlatDiscount(amount) and PercentDiscount(percent). Add a mixin Describable with describe() that prints runtimeType, and an extension on int with a getter rupees. Apply both discounts to 1000 and print the results with the extension.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Dart 3: enums, records, patterns and sealed classesNull safety and object-oriented Dart · same module
- Sound null safetyNull safety and object-oriented Dart · same module
- Inheritance and interfacesKotlin and Android App Development · Classes, objects and collections
- Inheritance with extendsJava Programming (Core to Spring Boot) · Inheritance, polymorphism and interfaces
- Interview questions: DartFlutter careers and interviews
- Inheritance and compositionJavaScript Programming (language in depth) · Scope, this, prototypes and classes
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
How many classes can a Dart class extend?
Answer: One
Single inheritance; many interfaces and mixins.
Which keyword adds a mixin?
Answer: with
class X with MyMixin.
What does an extension method change in the original class?
Answer: Nothing; it adds methods usable where the extension is imported
Extensions are compile-time helpers.
Which statement about implicit interfaces is true?
Answer: Every class defines an interface other classes can implement
Any class can be implemented.
How many classes can a Kotlin class extend?Related
How many classes can a Java class directly extend?Related
Which keyword creates a compile-time constant?Related
class B extends A {} (no constructor). What does new B(1, 2) do?Related
Answer: Calls A's constructor with 1, 2
A missing constructor in a subclass passes all arguments to super automatically.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Null safety and object-oriented Dart” before its exam: Dart 3: enums, records, patterns and sealed classes.
- Module 2 exam: Null safety and object-oriented Dart · 13 questions · 25 min, without help. 4 topics of this module still to finish first.
- Then the next module, Async Dart and packages. 50 topics left in the course before the final exam.