Menu
Coddy logo textTech

Gettery i settery — szczegółowo

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 33 z 110.

Gettery i settery stają się potężnymi narzędziami enkapsulacji w połączeniu z polami prywatnymi. Pozwalają udostępnić przejrzysty interfejs publiczny, zachowując pełną kontrolę nad tym, jak dane są odczytywane i modyfikowane.

Często stosuje się wzorzec polegający na połączeniu pola prywatnego z publicznym akcesorem odczytu oraz akcesorem zapisu, który obejmuje walidację:

class Temperature {
  double _celsius = 0;
  
  double get celsius => _celsius;
  
  set celsius(double value) {
    if (value < -273.15) {
      _celsius = -273.15;  // Minimum to zero absolutne
    } else {
      _celsius = value;
    }
  }
}

Settery mogą egzekwować reguły biznesowe, zapewniając, że Twój obiekt nigdy nie znajdzie się w nieprawidłowym stanie.

Możesz również tworzyć gettery obliczane, które wyznaczają wartości na podstawie danych prywatnych:

class Rectangle {
  double _width;
  double _height;
  
  Rectangle(this._width, this._height);
  
  double get area => _width * _height;      // Obliczane
  double get perimeter => 2 * (_width + _height);
  
  double get width => _width;
  set width(double value) {
    if (value > 0) _width = value;
  }
}

Czasami potrzebujesz dostępu tylko do odczytu. Wystarczy udostępnić getter bez settera:

class Order {
  final DateTime _createdAt = DateTime.now();
  
  DateTime get createdAt => _createdAt;  // Tylko do odczytu
}

Ten wzorzec zapewnia zewnętrznemu kodowi dostęp do danych, jednocześnie uniemożliwiając ich modyfikację — prywatne pole w połączeniu z samym getterem zapewnia rzeczywisty dostęp tylko do odczytu.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system zarządzania zapasami produktów, który pokaże możliwości getterów i setterów w kontrolowaniu dostępu do danych. Utworzysz klasę, która chroni swoje wewnętrzne dane, udostępniając jednocześnie właściwości obliczane i walidację.

Podzielisz kod na dwa pliki:

  • product.dart: Zdefiniuj klasę Product, która zarządza zapasami z użyciem prawidłowej enkapsulacji. Produkt powinien mieć:
    • Publiczne String name
    • Prywatne double _price
    • Prywatne int _quantity
    • Konstruktor przyjmujący wszystkie trzy wartości
    • Getter price, który zwraca prywatną cenę
    • Setter price, który akceptuje tylko wartości większe niż 0 (ignoruj nieprawidłowe wartości)
    • Getter quantity, który zwraca prywatną ilość
    • Setter quantity, który akceptuje tylko wartości równe 0 lub większe (ignoruj wartości ujemne)
    • Obliczany getter totalValue, który zwraca _price * _quantity
    • Obliczany getter isInStock, który zwraca true, jeśli ilość jest większa niż 0
    • Tylko do odczytu getter sku, który generuje prosty SKU, zwracając pierwsze 3 znaki nazwy zapisane wielkimi literami, a następnie ilość (np. LAP25 dla "Laptop" z ilością 25)
    • Metoda displayProduct(), która wyświetla szczegóły produktu
  • main.dart: Zaimportuj klasę produktu i pokaż, jak gettery i settery kontrolują dostęp:
    • Utwórz produkt o nazwie 'Laptop', cenie 999.99 i ilości 25
    • Wywołaj displayProduct()
    • Wypisz In stock: [isInStock]
    • Wypisz SKU: [sku]
    • Spróbuj ustawić cenę na -50.0 (powinna zostać zignorowana)
    • Ustaw cenę na 899.99 (prawidłowa zmiana)
    • Spróbuj ustawić ilość na -10 (powinna zostać zignorowana)
    • Ustaw ilość na 0 (prawidłowa zmiana)
    • Wywołaj displayProduct()
    • Wypisz In stock: [isInStock]
    • Wypisz SKU: [sku]

Metoda displayProduct() powinna wypisywać dane w tym formacie:

--- Product Info ---
Name: [name]
Price: $[price]
Quantity: [quantity]
Total Value: $[totalValue]

Oczekiwany wynik:

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

Spróbuj swoich sił

import 'product.dart';

void main() {
  // TODO: Utwórz produkt o nazwie 'Laptop', cenie 999.99 i ilości 25

  // TODO: Wywołaj displayProduct()

  // TODO: Wypisz "In stock: [isInStock]"

  // TODO: Wypisz "SKU: [sku]"

  // TODO: Spróbuj ustawić cenę na -50.0 (powinno zostać zignorowane)

  // TODO: Ustaw cenę na 899.99 (poprawna zmiana)

  // TODO: Spróbuj ustawić ilość na -10 (powinno zostać zignorowane)

  // TODO: Ustaw ilość na 0 (poprawna zmiana)

  // TODO: Wywołaj displayProduct()

  // TODO: Wypisz "In stock: [isInStock]"

  // TODO: Wypisz "SKU: [sku]"
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online