Berechnete Eigenschaften
Teil des Abschnitts Objektorientierte Programmierung der Lua-Journey von Coddy. Lektion 15 von 70.
Getter und Setter ermöglichen den Zugriff auf gespeicherte Werte, aber manchmal benötigst du Daten, die nicht als gespeichertes Feld existieren. Sie müssen aus anderen Attributen berechnet werden. Diese werden als berechnete Eigenschaften bezeichnet.
Betrachte ein Rechteck. Du speicherst seine Breite und Höhe, aber die Fläche wird nirgendwo gespeichert: Sie wird berechnet, indem diese beiden Werte miteinander multipliziert werden. Anstatt redundante Daten zu speichern, erstellst du eine Methode, die das Ergebnis berechnet und zurückgibt:
local Rectangle = {}
Rectangle.__index = Rectangle
function Rectangle:new(width, height)
local instance = {}
setmetatable(instance, self)
instance.width = width
instance.height = height
return instance
end
function Rectangle:getArea()
return self.width * self.height
endDie Methode :getArea() gibt keinen gespeicherten Wert zurück. Sie berechnet die Fläche jedes Mal neu, wenn du sie aufrufst. Dieser Ansatz hat einen entscheidenden Vorteil: Wenn sich die Breite oder Höhe ändert, spiegelt die Fläche automatisch die neuen Abmessungen wider, ohne dass du etwas aktualisieren musst.
local box = Rectangle:new(5, 3)
print(box:getArea()) -- Ausgabe: 15
box.width = 10
print(box:getArea()) -- Ausgabe: 30Berechnete Eigenschaften halten deine Objekte konsistent. Anstatt Werte zu speichern, die von anderen Feldern abhängen (und zu riskieren, dass sie veraltet werden), berechnest du sie bei Bedarf. Dieses Muster gilt für alle abgeleiteten Daten: Umfänge, Durchschnitte, formatierte Zeichenfolgen oder jeden Wert, der anhand vorhandener Attribute bestimmt werden kann.
Aufgabe
EinfachErstellen wir eine Box-Klasse, die ihr Volumen bei Bedarf berechnet! Anstatt das Volumen als Feld zu speichern, erstellst du eine berechnete Eigenschaft, die es aus den Abmessungen der Box berechnet, wann immer es benötigt wird.
Du wirst deinen Code auf zwei Dateien aufteilen:
Box.lua: Definiere deineBox-Klasse mit dem standardmäßigen Prototyp-Muster. Jede Box speichert drei Abmessungen:width,heightunddepth. Füge Folgendes hinzu:- Einen Konstruktor
:new(width, height, depth), der alle drei Abmessungen speichert - Eine Methode
:getVolume(), die das Volumen berechnet und zurückgibt (Breite × Höhe × Tiefe) - Eine Methode
:getSurfaceArea(), die die gesamte Oberfläche berechnet und zurückgibt
- Einen Konstruktor
main.lua: Binde dein Box-Modul ein, erstelle eine Box-Instanz und zeige, wie die berechneten Eigenschaften automatisch die aktuellen Abmessungen widerspiegeln.
Die Oberfläche einer Box wird folgendermaßen berechnet: 2 × (width×height + height×depth + width×depth)
Du erhältst drei Eingaben, die die Abmessungen der Box darstellen:
- Breite
- Höhe
- Tiefe
Erstelle in deiner Hauptdatei eine Box mit den angegebenen Abmessungen und gib anschließend zwei Zeilen aus:
- Das Volumen mit
:getVolume() - Die Oberfläche mit
:getSurfaceArea()
Wenn die Eingaben beispielsweise 3, 4 und 5 lauten, sollte die Ausgabe folgendermaßen aussehen:
60
94Das Schöne an berechneten Eigenschaften ist, dass sie immer korrekt bleiben. Wenn du später eine der Abmessungen der Box änderst, würde ein erneuter Aufruf von :getVolume() automatisch den korrekten neuen Wert zurückgeben: Keine manuellen Aktualisierungen erforderlich!
Probier es selbst
-- Box-Modul einbinden
local Box = require('Box')
-- Eingabedimensionen lesen
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())
-- TODO: Erstelle eine Box-Instanz mit den gegebenen Dimensionen
-- TODO: Gib das Volumen mit :getVolume() aus
-- TODO: Gib die Oberfläche mit :getSurfaceArea() aus
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Das 'self'-Konzept
Tabellen mit FunktionenExplizites 'self'Die Doppelpunkt-SyntaxPunkt vs. DoppelpunktZusammenfassung – Beweglicher Punkt4Projekt: Digitale Bank
Projekt-SetupEinzahlungsmethode7Polymorphie & Überschreiben
Methoden überschreibenElternmethoden aufrufenDuck TypingGemeinsames InterfaceTyp prüfenRückblick - Mitarbeiterrollen10Projekt: Formen-Manager
Projekt-SetupRechteck-KlasseKreis-KlasseUmfang-MethodeFormen-SammlungGesamtflächeFormen filtern2Klassen-Prototyp-Muster
Das Prototyp-KonzeptVerknüpfung mit __indexDer :new()-KonstruktorAttribute initialisierenUnabhängige InstanzenZusammenfassung – Autofabrik5Operatorüberladung in OOP
Objekte addierenObjekte subtrahierenObjekte verkettenObjekte vergleichen (<, >)Rückblick – Wallet-Mathematik3Objektzustand und -verhalten
InstanzvariablenGetter-MethodenSetter-MethodenBerechnete EigenschaftenStrings formatierenGleichheitsprüfungenZusammenfassung – Studentennote6Grundlagen der Vererbung
Das Vererbungs-SetupMethoden vererbenDen Konstruktor erweiternChild-Methoden hinzufügenGemeinsam vs. EinzigartigZusammenfassung - Formen-Hierarchie9Komposition & Mixins
Has-A-BeziehungDelegationEinfache MixinsAnwendung mehrerer MixinsMixins vs. VererbungZusammenfassung – Roboter-Montage12Abschluss-Herausforderungen
Wiederholung - InventarsystemWiederholung - BenutzerverwaltungWiederholung - Score-TrackerFinaler OOP-CheckÜbe selbstständig: Online-Lua-Compiler