Vincoli sui generici
Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 67 di 110.
A volte hai bisogno che un tipo generico abbia determinate capacità. Per esempio, se vuoi confrontare elementi o accedere a proprietà specifiche, un T senza restrizioni non garantisce che tali funzionalità siano disponibili. I vincoli generici ti permettono di limitare i parametri di tipo a tipi specifici o alle loro sottoclassi.
Usa la parola chiave extends per vincolare un parametro di tipo:
class NumberBox<T extends num> {
T value;
NumberBox(this.value);
T doubled() => (value * 2) as T;
}
void main() {
var intBox = NumberBox<int>(5);
var doubleBox = NumberBox<double>(3.5);
print(intBox.doubled()); // 10
print(doubleBox.doubled()); // 7.0
// var stringBox = NumberBox<String>('hi'); // Errore!
}Poiché T extends num, il compilatore sa che value supporta operazioni numeriche come la moltiplicazione. Senza questo vincolo, la chiamata value * 2 non funzionerebbe.
I vincoli funzionano anche con le tue gerarchie di classi:
abstract class Animal {
String get name;
}
class Dog extends Animal {
String get name => 'Dog';
}
class Shelter<T extends Animal> {
List<T> animals = [];
void add(T animal) => animals.add(animal);
void printNames() {
for (var animal in animals) {
print(animal.name); // Sicuro: T garantisce che 'name' esista
}
}
}I vincoli generici combinano la flessibilità dei generics con la sicurezza di sapere quali operazioni sono disponibili sul tuo tipo.
Sfida
FacileCostruiamo un calcolatore di statistiche che funziona solo con tipi numerici! Creerai una classe generica con un vincolo che ne garantisce l'utilizzo solo con i numeri, permettendoti di eseguire in sicurezza operazioni matematiche sui valori memorizzati.
Organizzerai il codice in due file:
stats.dart: crea una classe genericaStats<T extends num>che gestisce un elenco di valori numerici:- Una
List<T>chiamatavaluesper memorizzare i numeri - Un costruttore che inizializza l'elenco con i valori forniti
- Un metodo
sum()che restituisce la somma di tutti i valori comenum - Un metodo
min()che restituisce il valore più piccolo comeT - Un metodo
max()che restituisce il valore più grande comeT - Un metodo
printStats()che mostra le statistiche in un formato ordinato
- Una
main.dart: importa il file delle statistiche e mostra la classe generica vincolata con diversi tipi numerici:- Crea un
Stats<int>con i valori[10, 25, 5, 30, 15]e chiamaprintStats() - Stampa una riga vuota
- Crea un
Stats<double>con i valori[3.5, 1.2, 4.8, 2.1]e chiamaprintStats()
- Crea un
Il metodo printStats() dovrebbe produrre tre righe che mostrano la somma, il valore minimo e quello massimo. Poiché T extends num, puoi usare in sicurezza gli operatori di confronto e le operazioni aritmetiche sui valori: qualcosa che non sarebbe possibile con un tipo generico senza vincoli.
Output previsto:
Sum: 85
Min: 5
Max: 30
Sum: 11.6
Min: 1.2
Max: 4.8Provalo tu
import 'stats.dart';
void main() {
// TODO: Crea un Stats<int> con i valori [10, 25, 5, 30, 15]
// e chiama printStats()
// TODO: Stampa una riga vuota
// TODO: Crea un Stats<double> con i valori [3.5, 1.2, 4.8, 2.1]
// e chiama printStats()
}
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