Menu
Coddy logo textTech

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);     // null

Lorsque 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 optionnel

En 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.

challenge icon

Défi

Facile

Construisons 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 classe Reservation qui 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 guestName non-nullable - chaque réservation doit avoir un nom de client
    • Un int roomNumber non-nullable - chaque réservation doit se voir attribuer une chambre
    • Un int nights non-nullable avec une valeur par défaut de 1 - le séjour minimum est d'une nuit
    • Un String? specialRequests nullable - les clients peuvent avoir des demandes spéciales
    • Un DateTime? checkInTime nullable - l'heure d'arrivée exacte peut ne pas être connue
    • Un constructeur utilisant des paramètres nommés avec required pour guestName et roomNumber, tandis que nights doit ê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 ?., ou null si elle n'est pas définie
    • Une méthode printConfirmation() qui affiche les détails de la réservation
  • 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 chambre 101 pour 3 nuits, 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 chambre 205 (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 chambre 310 pour 2 nuits (laissez les deux champs optionnels à null)
    • Pour chaque réservation dans l'ordre, appelez printConfirmation(), puis affichez Arrival: [result] en utilisant getArrivalInfo()

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: null

Aide-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);  // null

Accé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()
}
quiz iconTestez-vous

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