Classes génériques
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 65 sur 110.
Tu as vu comment les collections intégrées de Dart, comme List<String>, utilisent des paramètres de type. Il est maintenant temps de créer tes propres classes génériques qui fonctionnent avec n’importe quel type que tu spécifies.
Une classe générique utilise un paramètre de type (généralement T) comme espace réservé pour le type réel qui sera fourni lors de la création d’une instance :
class Box<T> {
T content;
Box(this.content);
T getContent() => content;
}
void main() {
var stringBox = Box<String>('Hello');
var intBox = Box<int>(42);
print(stringBox.getContent()); // Hello
print(intBox.getContent()); // 42
}Le T agit comme une variable de type : lorsque vous créez Box<String>, chaque T de la classe devient String. Cela vous offre la sécurité de typage sans avoir à écrire des classes distinctes pour chaque type.
Vous pouvez utiliser plusieurs paramètres de type lorsque votre classe doit fonctionner avec plusieurs types :
class Pair<K, V> {
K first;
V second;
Pair(this.first, this.second);
}
void main() {
var pair = Pair<String, int>('age', 25);
print('${pair.first}: ${pair.second}'); // age: 25
}Les classes génériques sont la base d’un code réutilisable et sûr du point de vue des types. Au lieu de dupliquer la logique pour différents types ou de perdre les informations de type avec dynamic, les génériques vous permettent d’écrire du code flexible que le compilateur peut tout de même vérifier.
Défi
FacileConstruisons un système d’emballage de cadeaux qui utilise des classes génériques pour créer des conteneurs flexibles pour différents types d’éléments. Vous allez créer une classe générique Wrapper capable d’envelopper n’importe quel type de contenu, ainsi qu’une classe GiftBox avec deux paramètres de type pour associer un cadeau à un message sur une carte.
Vous organiserez votre code en deux fichiers :
wrapper.dart: définissez vos classes génériques ici :- Une classe générique
Wrapper<T>avec une propriétéT contentet un constructeur. Incluez une méthodeunwrap()qui renvoie le contenu, ainsi qu’une méthodedescribe()qui afficheWrapped: [content] - Une classe générique
GiftBox<G, C>avec deux propriétés :G giftetC card. Incluez un constructeur et une méthodeopen()qui afficheGift: [gift]sur une ligne etCard: [card]sur la ligne suivante
- Une classe générique
main.dart: importez votre fichier de wrapper et faites la démonstration des classes génériques avec différents types :- Créez un
Wrapper<String>contenant'Chocolate'et appelezdescribe() - Créez un
Wrapper<int>contenant42et appelezdescribe() - Créez un
Wrapper<double>contenant3.14et appelezdescribe() - Affichez une ligne vide
- Créez un
GiftBox<String, String>avec le cadeau'Teddy Bear'et la carte'Happy Birthday!', puis appelezopen() - Affichez une ligne vide
- Créez un
GiftBox<int, String>avec le cadeau100(représentant le montant d’une carte-cadeau) et la carte'Congratulations!', puis appelezopen()
- Créez un
Remarquez comment la même classe Wrapper fonctionne parfaitement avec des chaînes de caractères, des entiers et des nombres décimaux. La classe GiftBox montre comment utiliser deux paramètres de type pour associer différents types : le cadeau peut être de n’importe quel type, tandis que le message de la carte reste une chaîne de caractères.
Résultat attendu :
Wrapped: Chocolate
Wrapped: 42
Wrapped: 3.14
Gift: Teddy Bear
Card: Happy Birthday!
Gift: 100
Card: Congratulations!Essayez vous-même
import 'wrapper.dart';
void main() {
// TODO: Créez un Wrapper<String> contenant 'Chocolate' et appelez describe()
// TODO: Créez un Wrapper<int> contenant 42 et appelez describe()
// TODO: Créez un Wrapper<double> contenant 3.14 et appelez describe()
// TODO: Affichez une ligne vide
// TODO: Create a GiftBox<String, String> with gift 'Teddy Bear'
// and card 'Happy Birthday!', then call open()
// TODO: Affichez une ligne vide
// TODO: Créez un GiftBox<int, String> avec le cadeau 100
// and card 'Congratulations!', then call open()
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBibliothèques et importsIntroduction à la POOClasses vs objetsLe mot-clé thisMéthodesVariables d’instanceBases des constructeursRécapitulatif - Calculatrice simple4Sécurité face aux valeurs nulles
Introduction à la sécurité face aux valeurs nullesNullable vs Non-NullableLes opérateurs ? et !Mot-clé Late et sécurité face aux valeurs nullesOpérateurs sensibles à nullSécurité face aux valeurs nulles dans les classesRécapitulatif – Système de profil utilisateur7Classes abstraites et interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémenter ou étendreInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et génériques
Vue d’ensemble des List, Set et MapCollections à typage sûrClasses génériquesMéthodes génériquesContraintes génériquesIterable et IteratorRécapitulatif – stockage générique2Constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs redirigésRécapitulatif - Constructeur de formes5Encapsulation
Membres publics vs privésLa convention du préfixe _Confidentialité au niveau de la bibliothèqueApprofondissement des getters et settersMasquage de l’informationRécapitulatif - Fiches des étudiants8Mixins
Introduction aux MixinsCréer des MixinsUtiliser plusieurs MixinsMot-clé on dans les MixinsMixin ou héritageMixin ou interfaceRécapitulatif - Système animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode et ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy3Propriétés des classes
Membres d’instance et statiquesChamps Final et ConstVariables différéesMéthodes et champs statiquesAccesseurs et mutateursRécapitulatif - Gestionnaire de compte bancaire6Héritage
Héritage de baseLe mot-clé superRedéfinition de méthodeL’annotation @overrideLe mot-clé de classe finalConstructeurs et héritageRécapitulatif – Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification des types à l’exécutionLes opérateurs is et asMot-clé covariantRécapitulatif - Processeur de paiements12POO asynchrone
Futures et async/awaitNotions de base des StreamsContrôleurs de StreamsConstructeurs asynchronesAsynchrone dans les méthodes de classeRécapitulatif - récupérateur de données15Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron DépôtEntraînez-vous par vous-même : Compilateur Dart en ligne