Lesson 12 · 12 of 20
Operators, == and hashCode · Dart
Define operators on your Dart classes, compare objects by value with == and hashCode, and sort them with Comparable, using a Money type.

In Dart, operators are methods with a special name: `operator +`, operator *, operator <… Money stores cents and a currency, and defines + to add amounts (throwing an ArgumentError when the currencies differ), * to multiply by a quantity and < to compare. That way, coffee * 2 + croissant reads like a café bill.
By default, == compares identity: two objects are equal only if they are the same object. To make two Money(150) equal you override `operator ==`, which takes an Object, checks the type with is Money and compares the fields. identical still says false: they are equal, but not the same object.
Golden rule: if you override ==, override `hashCode` too, so that equal objects produce the same number. Object.hash(cents, currency) computes it from the same fields == compares. Sets and maps rely on it to look things up, which is why the set {coffee, Money(150), croissant} ends up with only two prices.
Implementing `Comparable<Money>` with compareTo gives the class a natural order, and sort() uses it with no extra arguments. toString() decides how the object is printed, inside lists and sets too. The last case shows the error when adding euros to dollars.
Code · main.dart
class Money implements Comparable<Money> { final int cents; final String currency; const Money(this.cents, [this.currency = 'EUR']); Money operator +(Money other) { if (other.currency != currency) throw ArgumentError('$currency + ${other.currency}'); return Money(cents + other.cents, currency); } Money operator *(int times) => Money(cents * times, currency); bool operator <(Money other) => cents < other.cents; @override int compareTo(Money other) => cents.compareTo(other.cents); // for sort() // Equal by value: same amount and currency. hashCode must agree with ==. @override bool operator ==(Object other) => other is Money && other.cents == cents && other.currency == currency; @override int get hashCode => Object.hash(cents, currency); @override String toString() => '${(cents / 100).toStringAsFixed(2)} $currency';}void main() { final coffee = Money(150), croissant = Money(195); print('Order: ${coffee * 2 + croissant}, cheaper: ${coffee < croissant}'); print('== ${Money(150) == coffee}, identical ${identical(Money(150), coffee)}'); print('Distinct prices: ${{coffee, Money(150), croissant}}'); // a Set print('Sorted: ${[Money(999), coffee, croissant]..sort()}'); try { coffee + Money(150, 'USD'); } on ArgumentError catch (e) { print('Cannot add ${e.message}'); }}Output · dart run main.dart
Order: 4.95 EUR, cheaper: true
== true, identical false
Distinct prices: {1.50 EUR, 1.95 EUR}
Sorted: [1.50 EUR, 1.95 EUR, 9.99 EUR]
Cannot add EUR + USDKey points
operator +and friends define operators on your classes.- Override
==to compare by value. ==always goes withhashCode, computed from the same fields.Object.hashcombines several fields into one hash code.ComparableandcompareToletsort()order your objects.
Exercise
Add operator - to Money and work out the change a customer gets when paying the order with a 5-euro note (Money(500)).