Menu
Coddy logo textTech

Getter & Setter im Detail

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 33 von 110.

Getter und Setter werden in Kombination mit privaten Feldern zu mächtigen Werkzeugen für die Kapselung. Sie ermöglichen es Ihnen, eine saubere öffentliche Schnittstelle bereitzustellen, während Sie die volle Kontrolle darüber behalten, wie auf Daten zugegriffen wird und wie diese geändert werden.

Ein gängiges Muster besteht darin, ein privates Feld mit einem öffentlichen Getter und einem Setter zu kombinieren, der eine Validierung beinhaltet:

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

Setter können Geschäftsregeln erzwingen und so sicherstellen, dass Ihr Objekt niemals in einen ungültigen Zustand gerät.

Sie können auch berechnete Getter erstellen, die Werte aus privaten Daten ableiten:

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

Manchmal möchten Sie einen schreibgeschützten Zugriff. Geben Sie einfach einen Getter ohne einen Setter an:

class Order {
  final DateTime _createdAt = DateTime.now();
  
  DateTime get createdAt => _createdAt;  // Schreibgeschützt
}

Dieses Muster ermöglicht externem Code Einblick in die Daten, während gleichzeitig jegliche Modifikationen verhindert werden – das private Feld in Kombination mit einem reinen Getter erzeugt einen echten schreibgeschützten Zugriff.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Produktinventarsystem erstellen, das die Leistungsfähigkeit von Gettern und Settern zur Steuerung des Datenzugriffs demonstriert. Sie werden eine Klasse erstellen, die ihre internen Daten schützt und gleichzeitig berechnete Eigenschaften und Validierungen bereitstellt.

Sie werden Ihren Code in zwei Dateien organisieren:

  • product.dart: Definieren Sie eine Klasse Product, die das Inventar mit ordnungsgemäßer Kapselung verwaltet. Ihr Produkt sollte Folgendes haben:
    • Einen öffentlichen String name
    • Einen privaten double _price
    • Einen privaten int _quantity
    • Einen Konstruktor, der alle drei Werte entgegennimmt
    • Einen Getter price, der den privaten Preis zurückgibt
    • Einen Setter price, der nur Werte größer als 0 akzeptiert (ungültige Werte ignorieren)
    • Einen Getter quantity, der die private Menge zurückgibt
    • Einen Setter quantity, der nur Werte von 0 oder größer akzeptiert (negative Werte ignorieren)
    • Einen berechneten Getter totalValue, der _price * _quantity zurückgibt
    • Einen berechneten Getter isInStock, der true zurückgibt, wenn die Menge größer als 0 ist
    • Einen schreibgeschützten Getter sku, der eine einfache SKU generiert, indem er die ersten 3 Zeichen des Namens in Großbuchstaben gefolgt von der Menge zurückgibt (z. B. LAP25 für "Laptop" mit der Menge 25)
    • Eine Methode displayProduct(), die die Produktdetails anzeigt
  • main.dart: Importieren Sie Ihre Produktklasse und demonstrieren Sie, wie Getter und Setter den Zugriff steuern:
    • Erstellen Sie ein Produkt namens 'Laptop' mit dem Preis 999.99 und der Menge 25
    • Rufen Sie displayProduct() auf
    • Geben Sie In stock: [isInStock] aus
    • Geben Sie SKU: [sku] aus
    • Versuchen Sie, den Preis auf -50.0 zu setzen (sollte ignoriert werden)
    • Setzen Sie den Preis auf 899.99 (gültige Änderung)
    • Versuchen Sie, die Menge auf -10 zu setzen (sollte ignoriert werden)
    • Setzen Sie die Menge auf 0 (gültige Änderung)
    • Rufen Sie displayProduct() auf
    • Geben Sie In stock: [isInStock] aus
    • Geben Sie SKU: [sku] aus

Die Methode displayProduct() sollte in diesem Format drucken:

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

Erwartete Ausgabe:

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

Spickzettel

Getter und Setter bieten in Kombination mit privaten Feldern Kapselung und Kontrolle über den Datenzugriff.

Privates Feld mit Getter und Setter

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

Berechnete Getter

Getter können Werte aus privaten Daten ableiten:

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

Schreibgeschützter Zugriff

Stellen Sie einen Getter ohne Setter für schreibgeschützte Eigenschaften bereit:

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

Probier es selbst

import 'product.dart';

void main() {
  // TODO: Erstelle ein Produkt namens 'Laptop' mit dem Preis 999.99 und der Menge 25

  // TODO: Rufe displayProduct() auf

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

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

  // TODO: Versuche, den Preis auf -50.0 zu setzen (sollte ignoriert werden)

  // TODO: Setze den Preis auf 899.99 (gültige Änderung)

  // TODO: Versuche, die Menge auf -10 zu setzen (sollte ignoriert werden)

  // TODO: Setze die Menge auf 0 (gültige Änderung)

  // TODO: Rufe displayProduct() auf

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

  // TODO: Drucke "SKU: [sku]"
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung