# Inheritance, Interfaces, Abstract Classes and Mixins — Dart

Source: https://www.skillbyai.com/en/dart/c-inherit

> Reuse and share behaviour with extends, implements and mixins.

## Three ways to share behaviour

Dart supports **single inheritance** with `extends`: a subclass inherits the superclass's members, overrides methods with `@override`, and calls the parent with `super`. Every class also defines an **implicit interface**: another class can `implement` it (or several), promising to provide all its members, without inheriting any code, which is how you create test fakes. **Abstract classes** (`abstract class Shape`) cannot be instantiated and can declare abstract methods for subclasses to implement. **Mixins** add reusable behaviour to multiple class hierarchies: declare `mixin Timestamped { DateTime? updatedAt; void touch() => updatedAt = DateTime.now(); }` and apply it with `class Order extends Entity with Timestamped`. A mixin can restrict which classes use it with `on BaseClass`. Mixins are applied in order, and later mixins override earlier ones. Prefer composition and small interfaces; use mixins for genuinely cross-cutting helpers, and inheritance for real is-a relationships.

## extends, implements and with

An abstract base, an interface used for a fake, and a mixin.

```dart
abstract class PaymentGateway {
  Future<String> charge(String orderId, int amountPaise);
}

mixin Logging {
  void log(String message) => print('[${runtimeType}] $message');
}

class UpiGateway with Logging implements PaymentGateway {
  @override
  Future<String> charge(String orderId, int amountPaise) async {
    log('charging $amountPaise for $orderId');
    return 'upi_$orderId';
  }
}

class FakeGateway implements PaymentGateway {        // implements: no code inherited
  final charges = <(String, int)>[];
  @override
  Future<String> charge(String orderId, int amountPaise) async {
    charges.add((orderId, amountPaise));
    return 'fake_$orderId';
  }
}

abstract class Shape {
  double get area;
  String describe() => '$runtimeType with area ${area.toStringAsFixed(1)}';
}

class Rect extends Shape {
  Rect(this.w, this.h);
  final double w, h;
  @override
  double get area => w * h;
}
```

## Family, job role and skills

extends is family: you inherit traits from one parent. implements is a job role: you promise to do the duties, however you learnt them. with adds skills, like cooking or first aid, that people from any family can pick up.

**Quiz:** In Dart, how can a class promise to provide another class's members without inheriting its code?

- [ ] extends
- [x] implements
- [ ] with
- [ ] super

*Answer:* implements. Every class defines an implicit interface that other classes can implement.
