Nullable vs Non-Nullable
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 24 sur 110.
Maintenant que vous comprenez pourquoi la sécurité contre les valeurs nulles (null safety) est importante, voyons comment déclarer des variables qui peuvent contenir null. En Dart, vous rendez un type nullable en ajoutant un ? après le nom du type.
String name = 'Alice'; // Non-nullable - doit toujours avoir une valeur
String? nickname; // Nullable - peut être null ou une String
print(name); // Alice
print(nickname); // nullLa différence clé est que les types non-nullables garantissent qu'une valeur existe, tandis que les types nullables permettent explicitement l'absence de valeur. Cette distinction s'applique à tous les types :
int count = 10; // Doit avoir une valeur
int? optionalCount; // Peut être nul
List<String> items = []; // Doit être une liste (peut être vide)
List<String>? maybeItems; // Pourrait être nul (pas de liste du tout)Notez qu'une liste vide [] est différente de null. Une liste vide existe mais ne contient rien ; null signifie qu'aucune liste n'existe du tout.
Le compilateur applique ces règles strictement. Vous ne pouvez pas assigner null à une variable non-nullable, et vous ne pouvez pas utiliser une variable nullable là où une variable non-nullable est attendue sans avoir préalablement vérifié la présence de null :
String? maybeName = 'Bob';
// String definite = maybeName; // Erreur ! Impossible d'assigner une valeur nullable à une valeur non-nullableDans la prochaine leçon, vous apprendrez les opérateurs que Dart fournit pour travailler en toute sécurité avec des valeurs nullables.
Défi
FacileConstruisons un système de liste de films à regarder qui démontre la différence entre les informations obligatoires et les informations facultatives à l’aide de types nullable et non-nullable.
Tu vas créer deux fichiers pour organiser ton code :
movie.dart: définis une classeMoviequi représente un film dans ta liste de films à regarder. Chaque film doit avoir un titre et une année de sortie (ces informations sont toujours obligatoires), mais certains détails supplémentaires peuvent ne pas être disponibles pour tous les films. Ta classe doit avoir :- Un
String titlenon-nullable : chaque film doit avoir un titre - Un
int yearnon-nullable : chaque film doit avoir une année de sortie - Un
String? directornullable : le réalisateur peut être inconnu - Un
double? ratingnullable : tous les films n’ont pas encore été notés - Un constructeur qui prend
titleetyearcomme paramètres obligatoires - Une méthode
displayInfo()qui affiche les informations du film, en indiquantUnknownlorsque le réalisateur est manquant etNot ratedlorsque la note est manquante
- Un
main.dart: importe ta classe de film et crée une petite liste de films à regarder illustrant des données de film complètes et incomplètes :- Crée un film avec le titre
'Inception'et l’année2010, puis définis son réalisateur sur'Christopher Nolan'et sa note sur8.8 - Crée un film avec le titre
'The Matrix'et l’année1999, puis définis uniquement sa note sur8.7(laisse le réalisateur à null) - Crée un film avec le titre
'Upcoming Film'et l’année2025(laisse le réalisateur et la note à null) - Appelle
displayInfo()sur chaque film dans l’ordre indiqué ci-dessus
- Crée un film avec le titre
La méthode displayInfo() doit afficher exactement au format suivant :
[title] ([year])
Director: [director or "Unknown"]
Rating: [rating or "Not rated"]Remarque que les champs non-nullable (title et year) ont toujours la garantie d’avoir une valeur, tandis que les champs nullable (director? et rating?) peuvent rester non définis. Cela reflète des situations réelles dans lesquelles certaines données sont essentielles et d’autres facultatives.
Résultat attendu :
Inception (2010)
Director: Christopher Nolan
Rating: 8.8
The Matrix (1999)
Director: Unknown
Rating: 8.7
Upcoming Film (2025)
Director: Unknown
Rating: Not ratedEssayez vous-même
import 'movie.dart';
void main() {
// TODO: Créer un film avec le titre 'Inception' et l'année 2010
// Ensuite, définir son réalisateur sur 'Christopher Nolan' et sa note sur 8.8
// TODO: Créer un film avec le titre 'The Matrix' et l'année 1999
// Ensuite, définir uniquement sa note sur 8.7 (laisser le réalisateur à null)
// TODO: Créer un film avec le titre 'Upcoming Film' et l'année 2025
// Laisser à la fois le réalisateur et la note à null
// TODO: Appeler displayInfo() sur chaque film dans l'ordre
}
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