Ce face abstract
abstract class Forma este un concept general, nu un obiect concret: nu poți scrie Forma(). Rolul ei este să fie extinsă sau implementată de clase concrete (Cerc, Patrat).
O metodă fără corp (doar semnătura, terminată cu ;) este abstractă. Orice subclasă concretă trebuie să o implementeze, altfel analizorul dă eroare. Clasa abstractă poate avea și metode cu corp, câmpuri și constructori, pe care subclasele le moștenesc.
Metodele abstracte pot exista doar în clase abstracte. Clasele abstracte sunt folosite des ca interfețe; pentru o interfață „pură”, fără cod, Dart 3 are și abstract interface class.
Exemple
Exemplul 1: O metodă abstractă și una concretă
arie este abstractă, fiecare formă o calculează altfel; descrie este moștenită de toate.
abstract class Forma {
String get nume;
double arie();
void descrie() => print('$nume cu aria ${arie().toStringAsFixed(2)}');
}
class Cerc extends Forma {
final double raza;
Cerc(this.raza);
@override
String get nume => 'Cerc';
@override
double arie() => 3.14159 * raza * raza;
}
class Patrat extends Forma {
final double latura;
Patrat(this.latura);
@override
String get nume => 'Pătrat';
@override
double arie() => latura * latura;
}
void main() {
final forme = <Forma>[Cerc(1.5), Patrat(4)];
for (final f in forme) {
f.descrie();
}
}
Rezultat
Cerc cu aria 7.07
Pătrat cu aria 16.00
Exemplul 2: Șablon de algoritm
Clasa abstractă fixează pașii (genereaza), iar subclasele completează doar partea care diferă.
abstract class Raport {
String titlu();
List<String> randuri();
void genereaza() {
print('=== ${titlu()} ===');
randuri().forEach(print);
print('--- sfârșit ---');
}
}
class RaportVanzari extends Raport {
@override
String titlu() => 'Vânzări octombrie';
@override
List<String> randuri() => ['Cluj: 12.400 lei', 'Iași: 9.850 lei'];
}
void main() {
RaportVanzari().genereaza();
}
Rezultat
=== Vânzări octombrie ===
Cluj: 12.400 lei
Iași: 9.850 lei
--- sfârșit ---
Exemplul 3: Instanțierea unei clase abstracte
Analizorul oprește programul: o clasă abstractă nu se poate crea, iar o subclasă concretă trebuie să implementeze metoda abstractă.
abstract class Animal {
void suna();
}
class Caine extends Animal {}
void main() {
Animal();
}
Rezultatul lui dart analyze
error - main.dart:5:7 - Missing concrete implementation of 'Animal.suna'. Try implementing the missing method, or make the class abstract. - non_abstract_class_inherits_abstract_member
error - main.dart:8:3 - Abstract classes can't be instantiated. Try creating an instance of a concrete subtype. - instantiate_abstract_class
Greșeli frecvente
Forma()pentru o clasă abstractă:Abstract classes can't be instantiated. Creează o subclasă concretă sau folosește un constructorfactory.- O metodă fără corp într-o clasă care nu este
abstract: eroare. - Uitarea unei metode abstracte în subclasă:
Missing concrete implementation.
Comenzi înrudite
extends: Creează o subclasă care moștenește câmpurile și metodele altei clase și le poate înlocui.implements: O clasă promite că are toți membrii altor clase (interfețe) și îi scrie singură, fără să moștenească codul lor.interface: Modificator de clasă (Dart 3): în afara fișierului ei, clasa poate fi doar implementată, nu și extinsă.sealed: Clasă cu un set închis de subtipuri, toate în același fișier; switch-ul pe ea verifică dacă ai tratat toate cazurile.factory: Constructor care nu creează neapărat un obiect nou: poate întoarce unul din cache sau o subclasă.