operator în Dart

Definește ce fac operatorii (+, -, ==, [], < etc.) pentru obiectele unei clase.

Sintaxă
Tip operator +(Tip altul) => ...;
bool operator ==(Object altul) => ...;   // împreună cu hashCode
Tip operator [](int index) => ...;
void operator []=(int index, Tip valoare) { ... }

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-un Set.
  • Parametrul lui operator == trebuie să fie Object, nu tipul clasei: verifică tipul cu is î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.