Menu
Coddy logo textTech

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.

challenge icon

Défi

Facile

Construisons 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 classe Product qui gère l'inventaire avec une encapsulation appropriée. Votre produit doit avoir :
    • Un String name public
    • Un double _price privé
    • Un int _quantity privé
    • Un constructeur qui prend les trois valeurs
    • Un getter price qui retourne le prix privé
    • Un setter price qui n'accepte que des valeurs supérieures à 0 (ignorez les valeurs invalides)
    • Un getter quantity qui retourne la quantité privée
    • Un setter quantity qui n'accepte que des valeurs de 0 ou plus (ignorez les valeurs négatives)
    • Un getter calculé totalValue qui retourne _price * _quantity
    • Un getter calculé isInStock qui retourne true si la quantité est supérieure à 0
    • Un getter en lecture seule sku qui génère un SKU simple en retournant les 3 premiers caractères du nom en majuscules suivis de la quantité (par exemple, LAP25 pour "Laptop" avec une quantité de 25)
    • Une méthode displayProduct() qui affiche les détails du produit
  • 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 de 999.99 et une quantité de 25
    • 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]

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

Aide-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]"
}
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