Ce face get și set
Un getter este o metodă fără paranteze care se citește ca un câmp: dreptunghi.arie. Valoarea se calculează la fiecare citire, deci este mereu la zi. Un setter se apelează când scrii obiect.nume = valoare și poate verifica sau transforma valoarea.
Fiecare câmp obișnuit are automat un getter și (dacă nu este final) un setter. De aceea poți începe cu un câmp public și, mai târziu, să-l înlocuiești cu getter/setter fără să schimbi codul care îl folosește.
Un tipar frecvent: un câmp privat _valoare și un getter public valoare, fără setter. Din afară, proprietatea se poate citi, dar nu modifica.
Exemple
Exemplul 1: Proprietăți calculate
arie și estePatrat nu sunt stocate: se calculează din laturi la fiecare citire.
class Dreptunghi {
double latime, inaltime;
Dreptunghi(this.latime, this.inaltime);
double get arie => latime * inaltime;
double get perimetru => 2 * (latime + inaltime);
bool get estePatrat => latime == inaltime;
}
void main() {
final camera = Dreptunghi(4, 3.5);
print('Arie: ${camera.arie} m², perimetru: ${camera.perimetru} m');
camera.inaltime = 4;
print('Arie nouă: ${camera.arie} m², pătrat: ${camera.estePatrat}');
}
Rezultat
Arie: 14.0 m², perimetru: 15.0 m
Arie nouă: 16.0 m², pătrat: true
Exemplul 2: Setter cu validare
Nota se poate schimba doar cu o valoare între 1 și 10; altfel se aruncă RangeError.
class Nota {
final String materie;
int _valoare;
Nota(this.materie, this._valoare);
int get valoare => _valoare;
set valoare(int noua) {
if (noua < 1 || noua > 10) {
throw RangeError.range(noua, 1, 10, 'nota');
}
_valoare = noua;
}
}
void main() {
final n = Nota('Matematică', 7);
n.valoare = 9;
print('${n.materie}: ${n.valoare}');
try {
n.valoare = 11;
} on RangeError catch (e) {
print('Respins: ${e.message}, valoarea ${e.invalidValue}');
}
}
Rezultat
Matematică: 9
Respins: Invalid value, valoarea 11
Exemplul 3: Proprietate doar pentru citire
total are doar getter. Lista internă se schimbă doar prin adauga; din afară se primește o copie care nu se poate modifica.
class Cos {
final List<double> _preturi = [];
void adauga(double pret) => _preturi.add(pret);
double get total => _preturi.fold(0, (s, p) => s + p);
int get numarProduse => _preturi.length;
List<double> get preturi => List.unmodifiable(_preturi);
}
void main() {
final cos = Cos()
..adauga(12.5)
..adauga(30);
print('${cos.numarProduse} produse, total ${cos.total} lei');
print(cos.preturi);
}
Rezultat
2 produse, total 42.5 lei
[12.5, 30.0]
Greșeli frecvente
- Getter scris cu paranteze (
double get arie() => ...): eroare, getter-ul nu are listă de parametri. - Un setter care se apelează pe sine:
set nota(int v) { nota = v; }intră într-o recursivitate infinită. Scrie în câmpul privat_nota. - Calcule scumpe într-un getter folosit des: se refac la fiecare citire. Salvează rezultatul dacă datele nu se schimbă.
Comenzi înrudite
class: Definește un tip nou de obiect, cu câmpuri (date) și metode (comportament).this: Referință la obiectul curent, în interiorul metodelor și constructorilor unei clase.late: Amână inițializarea unei variabile nenule: valoarea se dă mai târziu sau se calculează la prima folosire.operator: Definește ce fac operatorii (+, -, ==, [], < etc.) pentru obiectele unei clase.