Ce face class
O clasă este un șablon pentru obiecte. Ea spune ce date are fiecare obiect (câmpurile) și ce poate face (metodele). În Dart totul este un obiect, chiar și numerele și funcțiile, iar fiecare obiect este o instanță a unei clase.
Un obiect nou se creează apelând constructorul clasei: Elev('Ana', 17). Cuvântul new este opțional din Dart 2 și nu se mai scrie. Câmpurile și metodele se folosesc cu punct: ana.nume, ana.saluta().
Un nume care începe cu _ (ex. _sold) este privat: se vede doar în fișierul (biblioteca) în care a fost declarat. Dart nu are cuvintele public, private sau protected. Metoda toString(), moștenită de la Object, decide ce afișează print(obiect).
Exemple
Exemplul 1: O clasă simplă
Elev are două câmpuri, un constructor și o metodă. Fiecare obiect își păstrează propriile valori.
class Elev {
String nume;
int varsta;
Elev(this.nume, this.varsta);
void prezinta() {
print('Sunt $nume și am $varsta ani.');
}
}
void main() {
final ana = Elev('Ana', 17);
final mihai = Elev('Mihai', 16);
ana.prezinta();
mihai.prezinta();
mihai.varsta++;
print('${mihai.nume} are acum ${mihai.varsta} ani.');
}
Rezultat
Sunt Ana și am 17 ani.
Sunt Mihai și am 16 ani.
Mihai are acum 17 ani.
Exemplul 2: toString pentru afișare
Fără toString, print ar afișa doar Instance of 'Produs'. Cu @override o înlocuim cu un text util.
class Produs {
final String nume;
final double pret;
Produs(this.nume, this.pret);
double pretCuTva() => pret * 1.21;
@override
String toString() => '$nume (${pret.toStringAsFixed(2)} lei)';
}
void main() {
final cafea = Produs('Cafea', 24.5);
print(cafea);
print('Cu TVA: ${cafea.pretCuTva().toStringAsFixed(2)} lei');
print([Produs('Lapte', 7.25), Produs('Pâine', 4)]);
}
Rezultat
Cafea (24.50 lei)
Cu TVA: 29.64 lei
[Lapte (7.25 lei), Pâine (4.00 lei)]
Exemplul 3: Câmp privat și metode care îl modifică
_sold nu poate fi schimbat din alt fișier decât prin metodele clasei, care verifică regulile.
class ContBancar {
final String titular;
double _sold = 0;
ContBancar(this.titular);
void depune(double suma) {
_sold += suma;
print('$titular a depus $suma lei. Sold: $_sold lei');
}
bool retrage(double suma) {
if (suma > _sold) {
print('$titular: fonduri insuficiente pentru $suma lei.');
return false;
}
_sold -= suma;
print('$titular a retras $suma lei. Sold: $_sold lei');
return true;
}
}
void main() {
final cont = ContBancar('Elena');
cont.depune(500);
cont.retrage(120);
cont.retrage(1000);
}
Rezultat
Elena a depus 500.0 lei. Sold: 500.0 lei
Elena a retras 120.0 lei. Sold: 380.0 lei
Elena: fonduri insuficiente pentru 1000.0 lei.
Greșeli frecvente
- Câmpuri non-null fără valoare:
String nume;fără constructor care să-l inițializeze dă eroareaNon-nullable instance field 'nume' must be initialized. - Să crezi că
_campeste privat față de alte clase: în Dart confidențialitatea este la nivel de fișier (bibliotecă), nu de clasă. - Compararea obiectelor cu
==fără să suprascriioperator ==: două obiecte cu aceleași date sunt diferite, pentru că se compară identitatea.
Comenzi înrudite
constructori: Funcțiile speciale care creează și inițializează obiectele unei clase.this: Referință la obiectul curent, în interiorul metodelor și constructorilor unei clase.get și set: Proprietăți calculate (get) și proprietăți cu validare la atribuire (set), folosite ca niște câmpuri.static: Membri care aparțin clasei, nu fiecărui obiect: se folosesc prin numele clasei, ca Nume.camp.extends: Creează o subclasă care moștenește câmpurile și metodele altei clase și le poate înlocui.