Ce face operator
Cu operator poți da sens operatorilor pentru clasele tale: suma1 + suma2, vector * 2, catalog['Ana']. Se pot redefini + - * / ~/ % < > <= >= == [] []= unary- ~ & | ^ << >> >>>.
== decide când două obiecte sunt „egale”. Implicit compară identitatea (același obiect). Dacă îl suprascrii, suprascrie și hashCode, astfel încât obiectele egale să aibă același hash; altfel Set și Map nu funcționează corect.
Operatorii !=, += și altele compuse nu se definesc separat: a != b înseamnă !(a == b), iar a += b înseamnă a = a + b.
Exemple
Exemplul 1: Adunarea a două sume de bani
Banii sunt ținuți în bani întregi (1 leu = 100 de bani) ca să evităm erorile de rotunjire.
class Lei {
final int bani;
const Lei(this.bani);
Lei operator +(Lei alta) => Lei(bani + alta.bani);
Lei operator *(int ori) => Lei(bani * ori);
bool operator >(Lei alta) => bani > alta.bani;
@override
String toString() => '${bani ~/ 100},${(bani % 100).toString().padLeft(2, '0')} lei';
}
void main() {
const cafea = Lei(1250);
const croissant = Lei(875);
final total = cafea * 2 + croissant;
print('Total: $total');
print(total > const Lei(3000));
}
Rezultat
Total: 33,75 lei
true
Exemplul 2: == și hashCode
Două puncte cu aceleași coordonate sunt egale, iar setul le păstrează o singură dată.
class Punct {
final int x, y;
const Punct(this.x, this.y);
@override
bool operator ==(Object other) => other is Punct && other.x == x && other.y == y;
@override
int get hashCode => Object.hash(x, y);
@override
String toString() => '($x, $y)';
}
void main() {
print(Punct(1, 2) == Punct(1, 2));
print(Punct(1, 2) != Punct(2, 1));
print({Punct(1, 2), Punct(1, 2), Punct(3, 4)});
}
Rezultat
true
true
{(1, 2), (3, 4)}
Exemplul 3: Operatorii [] și []=
Catalogul se folosește ca un map: catalog['Ana'] citește, catalog['Ana'] = 10 adaugă o notă.
class Catalog {
final Map<String, List<int>> _note = {};
List<int> operator [](String elev) => _note[elev] ?? const [];
void operator []=(String elev, int nota) {
_note.putIfAbsent(elev, () => []).add(nota);
}
}
void main() {
final catalog = Catalog();
catalog['Ana'] = 10;
catalog['Ana'] = 8;
catalog['Dan'] = 7;
print(catalog['Ana']);
print(catalog['Dan']);
print(catalog['Ioana']);
}
Rezultat
[10, 8]
[7]
[]
Greșeli frecvente
- Suprascrierea lui
==fărăhashCode: obiectele egale ajung de mai multe ori într-unSet. - Parametrul lui
operator ==trebuie să fieObject, nu tipul clasei: verifică tipul cuisîn corp. - Să încerci să definești
!=,+=sau&&: nu se pot redefini.
Comenzi înrudite
class: Definește un tip nou de obiect, cu câmpuri (date) și metode (comportament).get și set: Proprietăți calculate (get) și proprietăți cu validare la atribuire (set), folosite ca niște câmpuri.extension: Adaugă metode, getter-e și operatori unui tip existent (chiar și String sau int), fără să-l modifici.records: Grupuri de valori anonime și imutabile, de forma (a, b) sau (nume: a), ideale pentru a întoarce mai multe valori.