Classi sealed (Dart 3)
Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 85 di 110.
Dart 3 ha introdotto le classi sealed, che limitano le classi che possono estenderle o implementarle. Quando contrassegni una classe come sealed, solo le classi nello stesso file possono esserne sottotipi diretti. Questo crea un insieme chiuso di sottotipi noti.
sealed class Result {}
class Success extends Result {
final String data;
Success(this.data);
}
class Failure extends Result {
final String error;
Failure(this.error);
}La potenza delle classi sealed deriva dal controllo di esaustività. Quando esegui uno switch su un tipo sealed, il compilatore conosce tutti i possibili sottotipi e si assicura che tu li gestisca tutti:
String handleResult(Result result) {
return switch (result) {
Success(data: var d) => 'Got: $d',
Failure(error: var e) => 'Error: $e',
};
// Non serve un caso default: il compilatore sa che tutti i casi sono coperti!
}
void main() {
var success = Success('Hello');
var failure = Failure('Not found');
print(handleResult(success)); // Got: Hello
print(handleResult(failure)); // Error: Not found
}Se aggiungi un nuovo sottotipo a una classe sealed, il compilatore segnalerà ogni istruzione switch che non lo gestisce. Questo rende le classi sealed ideali per modellare stati, risultati o qualsiasi scenario in cui hai un insieme fisso di varianti. A differenza delle classi astratte, le classi sealed garantiscono che nessun codice esterno possa aggiungere sottotipi imprevisti.
Sfida
FacileCostruiamo un gestore di richieste di rete usando le classi sealed! Creerai un sistema type-safe che modella i diversi stati di una risposta di rete, assicurandoti che ogni possibile esito venga gestito correttamente.
Organizzerai il codice in due file:
response.dart: crea una gerarchia di classi sealed che rappresenti tutti i possibili stati di una risposta di rete:- Una classe sealed chiamata
NetworkResponseche funge da base per tutti i tipi di risposta - Una classe
Loadingche estendeNetworkResponsee include un campoString message(ad es., "Fetching data...") - Una classe
Successche estendeNetworkResponsee include un campoString datae un campoint statusCode - Una classe
Errorche estendeNetworkResponsee include un campoString errorMessagee un campoint errorCode
- Una classe sealed chiamata
main.dart: importa il tuo file delle risposte e crea una funzione che gestisca tutti i tipi di risposta usando un'espressione switch:- Crea una funzione
handleResponse(NetworkResponse response)che restituisca unaString - Usa un'espressione switch con il pattern matching per gestire ogni caso:
- Per
Loading: restituisciStatus: [message] - Per
Success: restituisciSuccess ([statusCode]): [data] - Per
Error: restituisciError ([errorCode]): [errorMessage]
- Per
- Crea tre istanze di risposta e stampa il risultato della gestione di ciascuna:
- Una
Loadingcon il messaggioPlease wait... - Una
Successcon i datiUser profile loadede il codice di stato200 - Un
Errorcon il messaggio di erroreNot founde il codice di errore404
- Una
- Crea una funzione
Il bello delle classi sealed è che il compilatore si assicura che tu gestisca ogni possibile tipo di risposta: non serve alcun caso predefinito!
Output previsto:
Status: Please wait...
Success (200): User profile loaded
Error (404): Not foundProvalo tu
import 'response.dart';
// TODO: Crea una funzione handleResponse(NetworkResponse response)
// che restituisca una String
// Usa un'espressione switch con pattern matching per gestire ogni caso:
// - Per Loading: restituisci "Status: [message]"
// - Per Success: restituisci "Success ([statusCode]): [data]"
// - Per Error: restituisci "Error ([errorCode]): [errorMessage]"
void main() {
// TODO: Crea un'istanza di Loading con message "Please wait..."
// TODO: Crea un'istanza di Success con data "User profile loaded" e codice di stato 200
// TODO: Crea un'istanza di Error con errorMessage "Not found" e errorCode 404
// TODO: Stampa il risultato della gestione di ogni risposta
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniLibrerie e importazioniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave thisMetodiVariabili di istanzaFondamenti dei costruttoriRiepilogo - Calcolatrice semplice4Sicurezza dei valori null
Introduzione alla sicurezza dei valori nullNullable e non nullableGli operatori ? e !La keyword late e la sicurezza dei valori nullOperatori null-awareSicurezza dei valori null nelle classiRiepilogo - Sistema di profili utente7Classi astratte e interfacce
Classi astratteMetodi astrattiInterfacce in DartInterfacce impliciteImplementare vs estendereInterfacce multipleRiepilogo - Calcolatore di forme10Collezioni e generici
Panoramica di List, Set e MapCollezioni sicure rispetto ai tipiClassi genericheMetodi genericiVincoli sui genericiIterable e IteratorRiepilogo - Archiviazione generica13Concetti avanzati di OOP
Composizione vs ereditarietàMetodi di estensioneClassi chiamabiliClassi sealed (Dart 3)Record (Dart 3)Pattern e matching (3.0)Enum con metodi16Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente2I costruttori in Dart
Costruttore predefinitoCostruttori con nomeListe di inizializzazioneCostruttori costantiCostruttori factoryCostruttori di reindirizzamentoRiepilogo - Crea forme5Incapsulamento
Membri pubblici e privatiConvenzione del prefisso _Visibilità a livello di libreriaApprofondimento su getter e setterNascondimento delle informazioniRiepilogo - Registri degli studenti8Mixin
Introduzione ai MixinCreare MixinUsare più MixinParola chiave on nei MixinMixin vs ereditarietàMixin vs interfacciaRiepilogo - Sistema animale11Metodi speciali
Sovrascrittura di toString()Sovrascrittura di hashCode e ==Interfaccia ComparableMetodo call()Sovrascrittura di noSuchMethodRiepilogo - Collezione personalizzata14Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneSingletonFactoryObserverStrategy3Proprietà delle classi
Membri di istanza e staticiCampi final e constVariabili lateMetodi e campi staticiGetter e setterRiepilogo - Gestore di conti bancari6Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiL’annotazione @overrideLa parola chiave final per le classiCostruttori ed ereditarietàRiepilogo - Gerarchia dei dipendenti9Polimorfismo
Fondamenti di polimorfismoPolimorfismo tramite interfacceControllo del tipo a runtimeGli operatori is e asParola chiave covariantRiepilogo - Elaboratore di pagamenti12OOP asincrona
Future e async/awaitNozioni di base sugli streamController degli streamCostruttori asincroniAsync nei metodi di classeRiepilogo - Recupero dei dati15Pattern di progettazione Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern RepositoryEsercitati da solo: Compilatore Dart online