Lección 12 · 12 de 20
Operadores, == y hashCode · Dart
Defina operadores en sus clases de Dart, compare objetos por valor con == y hashCode y ordénelos con Comparable, con un tipo Money.

En Dart, los operadores son métodos con un nombre especial: `operator +`, operator *, operator <… Money guarda céntimos y moneda, y define + para sumar importes (lanza ArgumentError si las monedas no coinciden), * para multiplicar por una cantidad y < para comparar. Así, coffee * 2 + croissant se lee como la cuenta de una cafetería.
Por defecto, == compara identidad: dos objetos son iguales solo si son el mismo. Para que dos Money(150) lo sean se sobrescribe `operator ==`, que recibe un Object, comprueba el tipo con is Money y compara los campos. identical sigue diciendo false: son iguales, pero no son el mismo objeto.
Regla de oro: si sobrescribe ==, sobrescriba también `hashCode`, de modo que dos objetos iguales den el mismo número. Object.hash(cents, currency) lo calcula a partir de los mismos campos que compara ==. Los Set y los Map lo usan para buscar, y por eso el conjunto {coffee, Money(150), croissant} se queda con solo dos precios.
Implementar `Comparable<Money>` con compareTo da a la clase un orden natural, y sort() lo usa sin más argumentos. toString() decide cómo se escribe el objeto, también dentro de listas y conjuntos. El último caso muestra el error al sumar euros con dólares.
Código · 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}'); }}Salida · 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 + USDPara recordar
operator +y compañía definen operadores en sus clases.- Sobrescriba
==para comparar por valor. - Con
==va siemprehashCode, calculado con los mismos campos. Object.hashcombina varios campos en un código hash.ComparableycompareTopermiten ordenar consort().
Ejercicio
Añada operator - a Money y calcule el cambio que recibe un cliente que paga el pedido con un billete de 5 euros (Money(500)).