La Null Safety dans les classes
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 28 sur 110.
Lors de la conception de classes, vous devez décider quels champs sont obligatoires et lesquels sont facultatifs. La sécurité contre les valeurs nulles (null safety) affecte la manière dont vous déclarez les variables d'instance et écrivez les constructeurs.
Les champs non-nullables doivent être initialisés avant l'exécution du corps du constructeur. Vous pouvez le faire via des listes d'initialisation, des paramètres de constructeur ou des valeurs par défaut :
class User {
String name; // Doit être initialisé
String? bio; // Optionnel - peut être nul
int age = 0; // A une valeur par défaut
User(this.name); // name est initialisé via le paramètre
}Pour les champs pouvant être nuls, vous pouvez les laisser non initialisés car ils ont par défaut la valeur null. C'est utile pour les données facultatives :
class Product {
String title;
String? description; // Description facultative du produit
double? discount; // Aucune remise par défaut
Product(this.title);
}
var item = Product('Laptop');
print(item.description); // null
print(item.discount); // nullLorsque vous accédez à des champs nullable, utilisez les opérateurs de gestion de la nullité que vous avez appris :
class Order {
String id;
User? customer;
Order(this.id);
String getCustomerName() {
return customer?.name ?? 'Guest';
}
}Le mot-clé required dans les paramètres nommés garantit que les appelants fournissent des valeurs essentielles :
class Account {
String email;
String? phone;
Account({required this.email, this.phone});
}
var acc = Account(email: 'test@mail.com'); // phone est optionnelEn choisissant judicieusement entre des champs nullables et non-nullables, vous créez des classes qui communiquent clairement quelles données sont essentielles et lesquelles sont facultatives.
Défi
FacileConstruisons un système de réservation pour un hôtel qui démontre comment concevoir des classes avec un mélange réfléchi de champs obligatoires et optionnels en utilisant la sécurité contre les valeurs nulles (null safety).
Vous organiserez votre code dans deux fichiers :
reservation.dart: Définissez une classeReservationqui représente une réservation d'hôtel. Chaque réservation nécessite certaines informations essentielles, mais certains détails sont des extras optionnels que les clients peuvent ou non fournir. Votre classe doit avoir :- Un
String guestNamenon-nullable - chaque réservation doit avoir un nom de client - Un
int roomNumbernon-nullable - chaque réservation doit se voir attribuer une chambre - Un
int nightsnon-nullable avec une valeur par défaut de1- le séjour minimum est d'une nuit - Un
String? specialRequestsnullable - les clients peuvent avoir des demandes spéciales - Un
DateTime? checkInTimenullable - l'heure d'arrivée exacte peut ne pas être connue - Un constructeur utilisant des paramètres nommés avec
requiredpourguestNameetroomNumber, tandis quenightsdoit être optionnel avec sa valeur par défaut - Une méthode
getRequestsSummary()qui retourne les demandes spéciales si elles sont fournies, ou'No special requests'en utilisant l'opérateur?? - Une méthode
getArrivalInfo()qui retourne la représentation sous forme de chaîne de caractères de l'heure d'enregistrement en utilisant?., ounullsi elle n'est pas définie - Une méthode
printConfirmation()qui affiche les détails de la réservation
- Un
main.dart: Importez votre classe de réservation et créez des réservations qui présentent différentes combinaisons de données obligatoires et optionnelles :- Créez une réservation pour le client
'Sarah Johnson'dans la chambre101pour3nuits, avec les demandes spéciales'Late checkout'et l'heure d'enregistrement fixée àDateTime(2024, 6, 15, 14, 30) - Créez une réservation pour le client
'Mike Chen'dans la chambre205(utilisez le nombre de nuits par défaut), avec seulement les demandes spéciales fixées à'Extra pillows' - Créez une réservation pour le client
'Emma Davis'dans la chambre310pour2nuits (laissez les deux champs optionnels à null) - Pour chaque réservation dans l'ordre, appelez
printConfirmation(), puis affichezArrival: [result]en utilisantgetArrivalInfo()
- Créez une réservation pour le client
La méthode printConfirmation() doit afficher les informations dans ce format :
=== Reservation Confirmed ===
Guest: [guestName]
Room: [roomNumber]
Nights: [nights]
Requests: [getRequestsSummary()]Résultat attendu :
=== Reservation Confirmed ===
Guest: Sarah Johnson
Room: 101
Nights: 3
Requests: Late checkout
Arrival: 2024-06-15 14:30:00.000
=== Reservation Confirmed ===
Guest: Mike Chen
Room: 205
Nights: 1
Requests: Extra pillows
Arrival: null
=== Reservation Confirmed ===
Guest: Emma Davis
Room: 310
Nights: 2
Requests: No special requests
Arrival: nullAide-mémoire
Les champs non-nullables doivent être initialisés avant l'exécution du corps du constructeur, tandis que les champs nullables peuvent rester non initialisés (par défaut à null) :
class User {
String name; // Doit être initialisé
String? bio; // Optionnel - par défaut à null
int age = 0; // A une valeur par défaut
User(this.name);
}Utilisez des champs nullables pour les données optionnelles :
class Product {
String title;
String? description; // Optionnel
double? discount; // Optionnel
Product(this.title);
}
var item = Product('Laptop');
print(item.description); // nullAccédez aux champs nullables avec des opérateurs sensibles à la nullité (null-aware) :
class Order {
String id;
User? customer;
Order(this.id);
String getCustomerName() {
return customer?.name ?? 'Guest';
}
}Utilisez le mot-clé required dans les paramètres nommés pour les valeurs essentielles :
class Account {
String email;
String? phone;
Account({required this.email, this.phone});
}
var acc = Account(email: 'test@mail.com');Essayez vous-même
import 'reservation.dart';
void main() {
// TODO: Créer une réservation pour 'Sarah Johnson'
// Chambre 101, 3 nuits, demandes spéciales : 'Late checkout'
// Heure d'arrivée : DateTime(2024, 6, 15, 14, 30)
// TODO: Créer une réservation pour 'Mike Chen'
// Chambre 205, utiliser le nombre de nuits par défaut, demandes spéciales : 'Extra pillows'
// Aucune heure d'arrivée spécifiée
// TODO: Créer une réservation pour 'Emma Davis'
// Chambre 310, 2 nuits, aucune demande spéciale, aucune heure d'arrivée
// TODO: Pour chaque réservation dans l'ordre :
// 1. Appeler printConfirmation()
// 2. Afficher 'Arrival: [result]' en utilisant getArrivalInfo()
}
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
1Les bases de la POO
Fichiers externesBibliothèques et importsIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesVariables d'instanceBases des constructeursRécapitulatif - Calculatrice simple4Null Safety
Introduction à la Null SafetyNullable vs Non-NullableLes opérateurs ? et !Le mot-clé late et la Null SafetyLes opérateurs Null-AwareLa Null Safety dans les classesRécapitulatif - Système de profil utilisateur7Classes abstraites et Interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémentation vs ExtensionInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et Génériques
Aperçu des List, Set et MapCollections Type-SafeClasses génériquesMéthodes génériquesContraintes de généricitéIterable & IteratorRécapitulatif - Stockage générique2Les constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs de redirectionRécapitulatif - Shape Builder5Encapsulation
Membres publics vs privésLa convention du préfixe _Visibilité au niveau de la bibliothèqueApprofondissement des Getters & SettersMasquage d'informationsRécapitulatif - Dossiers d'étudiants8Mixins
Introduction aux MixinsCréation de MixinsUtilisation de plusieurs MixinsLe mot-clé on dans les MixinsMixin vs HéritageMixin vs InterfaceRécapitulatif - Système Animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode & ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron ObservateurPatron Stratégie3Propriétés de classe
Membres d'instance vs statiquesChamps Final & ConstVariables LateMéthodes et champs statiquesGetters et SettersRécapitulatif - Gestionnaire de compte bancaire6Héritage
Bases de l'héritageLe mot-clé superRedéfinition de méthodeL'annotation @overrideLe mot-clé final pour les classesConstructeurs et héritageRécapitulatif - Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification de type à l'exécutionLes opérateurs is & asMot-clé covariantRécapitulatif - Processeur de paiement12POO Asynchrone
Futures & async/awaitBases des StreamsStream ControllersConstructeurs asynchronesL'asynchrone dans les méthodes de classeRécapitulatif - Data Fetcher15Patrons de conception Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode ModèlePatron ÉtatPatron CompositePatron Repository