Approfondissement des Getters & Setters
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 33 sur 110.
Les getters et les setters deviennent des outils puissants pour l'encapsulation lorsqu'ils sont combinés avec des champs privés. Ils vous permettent d'exposer une interface publique propre tout en gardant un contrôle total sur la manière dont les données sont consultées et modifiées.
Un modèle courant consiste à associer un champ privé à un getter public et un setter incluant une validation :
class Temperature {
double _celsius = 0;
double get celsius => _celsius;
set celsius(double value) {
if (value < -273.15) {
_celsius = -273.15; // Minimum du zéro absolu
} else {
_celsius = value;
}
}
}Les setters peuvent appliquer des règles métier, garantissant que votre objet n'entre jamais dans un état invalide.
Vous pouvez également créer des getters calculés qui dérivent des valeurs à partir de données privées :
class Rectangle {
double _width;
double _height;
Rectangle(this._width, this._height);
double get area => _width * _height; // Calculé
double get perimeter => 2 * (_width + _height);
double get width => _width;
set width(double value) {
if (value > 0) _width = value;
}
}Parfois, vous souhaitez un accès en lecture seule. Fournissez simplement un getter sans setter :
class Order {
final DateTime _createdAt = DateTime.now();
DateTime get createdAt => _createdAt; // Lecture seule
}Ce modèle donne au code externe une visibilité sur les données tout en empêchant toute modification - le champ privé combiné à un simple getter crée un véritable accès en lecture seule.
Défi
FacileConstruisons un système d'inventaire de produits qui met en avant la puissance des getters et des setters pour contrôler l'accès aux données. Vous allez créer une classe qui protège ses données internes tout en fournissant des propriétés calculées et une validation.
Vous organiserez votre code en deux fichiers :
product.dart: Définissez une classeProductqui gère l'inventaire avec une encapsulation appropriée. Votre produit doit avoir :- Un
String namepublic - Un
double _priceprivé - Un
int _quantityprivé - Un constructeur qui prend les trois valeurs
- Un getter
pricequi retourne le prix privé - Un setter
pricequi n'accepte que des valeurs supérieures à0(ignorez les valeurs invalides) - Un getter
quantityqui retourne la quantité privée - Un setter
quantityqui n'accepte que des valeurs de0ou plus (ignorez les valeurs négatives) - Un getter calculé
totalValuequi retourne_price * _quantity - Un getter calculé
isInStockqui retournetruesi la quantité est supérieure à0 - Un getter en lecture seule
skuqui génère un SKU simple en retournant les 3 premiers caractères du nom en majuscules suivis de la quantité (par exemple,LAP25pour "Laptop" avec une quantité de 25) - Une méthode
displayProduct()qui affiche les détails du produit
- Un
main.dart: Importez votre classe de produit et démontrez comment les getters et les setters contrôlent l'accès :- Créez un produit nommé
'Laptop'avec un prix de999.99et une quantité de25 - Appelez
displayProduct() - Affichez
In stock: [isInStock] - Affichez
SKU: [sku] - Tentez de régler le prix à
-50.0(devrait être ignoré) - Réglez le prix à
899.99(changement valide) - Tentez de régler la quantité à
-10(devrait être ignorée) - Réglez la quantité à
0(changement valide) - Appelez
displayProduct() - Affichez
In stock: [isInStock] - Affichez
SKU: [sku]
- Créez un produit nommé
La méthode displayProduct() doit afficher les informations dans ce format :
--- Product Info ---
Name: [name]
Price: $[price]
Quantity: [quantity]
Total Value: $[totalValue]Résultat attendu :
--- Product Info ---
Name: Laptop
Price: $999.99
Quantity: 25
Total Value: $24999.75
In stock: true
SKU: LAP25
--- Product Info ---
Name: Laptop
Price: $899.99
Quantity: 0
Total Value: $0.0
In stock: false
SKU: LAP0Aide-mémoire
Les getters et setters combinés aux champs privés permettent l'encapsulation et le contrôle de l'accès aux données.
Champ privé avec getter et setter
class Temperature {
double _celsius = 0;
double get celsius => _celsius;
set celsius(double value) {
if (value < -273.15) {
_celsius = -273.15;
} else {
_celsius = value;
}
}
}Getters calculés
Les getters peuvent dériver des valeurs à partir de données privées :
class Rectangle {
double _width;
double _height;
Rectangle(this._width, this._height);
double get area => _width * _height;
double get perimeter => 2 * (_width + _height);
double get width => _width;
set width(double value) {
if (value > 0) _width = value;
}
}Accès en lecture seule
Fournissez un getter sans setter pour les propriétés en lecture seule :
class Order {
final DateTime _createdAt = DateTime.now();
DateTime get createdAt => _createdAt;
}Essayez vous-même
import 'product.dart';
void main() {
// TODO: Créer un produit nommé 'Laptop' avec un prix de 999.99 et une quantité de 25
// TODO: Appeler displayProduct()
// TODO: Afficher "In stock: [isInStock]"
// TODO: Afficher "SKU: [sku]"
// TODO: Tenter de définir le prix à -50.0 (devrait être ignoré)
// TODO: Définir le prix à 899.99 (changement valide)
// TODO: Tenter de définir la quantité à -10 (devrait être ignorée)
// TODO: Définir la quantité à 0 (changement valide)
// TODO: Appeler displayProduct()
// TODO: Afficher "In stock: [isInStock]"
// TODO: Afficher "SKU: [sku]"
}
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