Ce face final class
final class închide complet clasa pentru celelalte biblioteci: nu poate fi extinsă (extends), nu poate fi implementată (implements) și nu poate fi folosită ca mixin. Autorul ei o poate modifica oricând fără să strice codul altcuiva.
Nu confunda cu variabilele final: aici cuvântul se aplică unei clase și se referă la moștenire, nu la valori. Obiectele unei final class pot avea câmpuri modificabile.
În același fișier poți încă extinde clasa, dar subclasele trebuie să fie și ele base, final sau sealed.
Exemple
Exemplul 1: O clasă de valoare închisă
Cnp verifică formatul în constructor. Fiind final, nimeni din altă bibliotecă nu poate crea un „CNP” care ocolește verificarea.
final class Cnp {
final String valoare;
Cnp(this.valoare) {
if (valoare.length != 13 || int.tryParse(valoare) == null) {
throw FormatException('CNP-ul trebuie să aibă 13 cifre', valoare);
}
}
String get sex => '1357'.contains(valoare[0]) ? 'masculin' : 'feminin';
}
void main() {
print(Cnp('2950412123456').sex);
try {
Cnp('12345');
} on FormatException catch (e) {
print('${e.message}: ${e.source}');
}
}
Rezultat
feminin
CNP-ul trebuie să aibă 13 cifre: 12345
Exemplul 2: Extinderea și implementarea din alt fișier
facturi.dart declară final class Factura. Din main.dart, ambele încercări sunt respinse.
// facturi.dart
final class Factura {
final double total;
Factura(this.total);
}
// main.dart
import 'facturi.dart';
class FacturaMea extends Factura {
FacturaMea() : super(10);
}
class FacturaFalsa implements Factura {
@override
double get total => 0;
}
Rezultatul lui dart analyze (al doilea fișier nu se compilează)
error - main.dart:3:26 - The class 'Factura' can't be extended outside of its library because it's a final class. - invalid_use_of_type_outside_library
error - main.dart:7:31 - The class 'Factura' can't be implemented outside of its library because it's a final class. - invalid_use_of_type_outside_library
Greșeli frecvente
- Să crezi că
final classface obiectele imutabile: câmpurile rămân modificabile dacă nu suntfinal. - Folosirea lui
final classpeste tot într-un pachet public: utilizatorii nu-ți mai pot crea implementări de test (mock-uri) cuimplements. - O subclasă din același fișier fără
base,finalsausealed: eroare.
Comenzi înrudite
base: Modificator de clasă (Dart 3): clasa poate fi extinsă, dar nu implementată în afara fișierului ei.sealed: Clasă cu un set închis de subtipuri, toate în același fișier; switch-ul pe ea verifică dacă ai tratat toate cazurile.interface: Modificator de clasă (Dart 3): în afara fișierului ei, clasa poate fi doar implementată, nu și extinsă.final: Declară o variabilă care primește valoarea o singură dată și nu mai poate fi reatribuită.