Lesson 6 · 6 of 20
Mixins · Dart
Reuse behaviour in Dart with mixins: with to apply them, on to restrict them and abstract members that ask the class for data.

Dart only lets a class extend one other class, yet several unrelated classes often need the same piece of behaviour. A `mixin` is that reusable piece: fields and methods that are mixed into a class with the `with` keyword.
Discountable adds a field, percentOff, and a getter, finalPrice, which takes off the percentage using integer division. `on Product` restricts it to classes that are a Product and, in exchange, it can safely use price: the compiler knows it will be there.
Shippable has no restriction and declares weightKg as abstract: the class that uses it must provide it. With that value it computes shippingCost, 399 cents up to one kilo and 699 above that. So a mixin can offer logic and, in return, demand the data it needs.
Book mixes in both (with Discountable, Shippable) and Ebook only the discount, because a digital book is never shipped. In main, the cascade ..percentOff = 20 sets the field the mixin brought along. Mixins are types too, and is recognises them: a Book is Discountable as well as a Product, while an Ebook is not Shippable.
Code · main.dart
abstract class Product { String get name; int get price; } // price in cents// A mixin adds fields and methods to any class that uses it.// "on Product" means it can only be mixed into products.mixin Discountable on Product { int percentOff = 0; int get finalPrice => price - price * percentOff ~/ 100;}mixin Shippable { double get weightKg; // the class must provide this int get shippingCost => weightKg <= 1 ? 399 : 699;}class Book extends Product with Discountable, Shippable { @override final String name = 'Clean Code'; @override final int price = 3500; @override final double weightKg = 0.8;}class Ebook extends Product with Discountable { @override final String name = 'Dart in Action (PDF)'; @override final int price = 1800;}void main() { final book = Book()..percentOff = 20; final ebook = Ebook()..percentOff = 50; print('${book.name}: ${book.finalPrice} + shipping ${book.shippingCost}'); print('${ebook.name}: ${ebook.finalPrice}, ships: ${ebook is Shippable}'); print('A Book is Discountable: ${book is Discountable}, is Product: ${book is Product}');}Output · dart run main.dart
Clean Code: 2800 + shipping 399 Dart in Action (PDF): 900, ships: false A Book is Discountable: true, is Product: true
Key points
- A
mixinreuses code across classes that share no inheritance. - Apply it with
with; several can be applied at once. on Classrestricts where it can be used and gives access to that class's members.- A mixin can require abstract members from the class using it.
- Mixins are types too: they work with
is.
Exercise
Create a Reviewable mixin with a list of scores and a rating getter that returns their average, apply it to Book and add two reviews.