Gleichheitsprüfungen
Teil des Abschnitts Objektorientierte Programmierung der Lua-Journey von Coddy. Lektion 17 von 70.
Du hast gesehen, wie __tostring steuert, wie ein Objekt sich selbst darstellt. Eine weitere nützliche Metamethode ist __eq, die festlegt, wann zwei Objekte mithilfe des Operators == als gleich betrachtet werden sollen.
Standardmäßig prüft der Vergleich zweier Tabellen mit ==, ob sie exakt dieselbe Tabelle im Speicher sind. Zwei separate Objekte mit identischen Daten geben false zurück:
local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2) -- Ausgabe: false (unterschiedliche Tabellen)Mit __eq kannst du deine eigene Gleichheitslogik definieren. In einer Klasse fügst du es genauso wie __tostring hinzu, als Funktion in der Klassentabelle. Damit der Gleichheitsvergleich funktioniert, müssen beide Objekte dieselbe Metatabelle verwenden:
local User = {}
User.__index = User
function User:new(id, name)
local instance = {}
setmetatable(instance, self)
instance.id = id
instance.name = name
return instance
end
function User:__eq(other)
return self.id == other.id
endNun gelten zwei User-Objekte als gleich, wenn sie dieselbe ID haben, unabhängig von anderen Feldern:
local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")
print(u1 == u2) -- Ausgabe: true (gleiche ID)
print(u1 == u3) -- Ausgabe: false (verschiedene IDs)Dieses Muster ist wertvoll, wenn Objekte reale Entitäten mit eindeutigen Bezeichnern darstellen: beim Vergleichen von Datenbankdatensätzen, Spieleentitäten oder beliebigen Objekten, bei denen die Identität wichtiger ist als der Speicherort.
Aufgabe
EinfachErstellen wir eine Product-Klasse, die feststellen kann, ob zwei Produkte derselbe Artikel sind, selbst wenn sie in völlig unterschiedlichen Tabellen gespeichert sind! In Einzelhandelssystemen haben Produkte häufig eindeutige SKU-Codes (Stock Keeping Units), und zwei Produkte sollten als gleich betrachtet werden, wenn sie dieselbe SKU haben, unabhängig von anderen Details wie Preisänderungen.
Du organisierst deinen Code über zwei Dateien:
Product.lua: Definiere deineProduct-Klasse mit dem standardmäßigen Prototyp-Muster. Jedes Produkt sollte einesku(die eindeutige Kennung) und einennamespeichern. Implementiere die Metamethode__eq, sodass zwei Produkte als gleich gelten, wenn sie dieselbe SKU haben: Der Name spielt für die Gleichheit keine Rolle.main.lua: Binde dein Product-Modul ein und erstelle mehrere Produktinstanzen. Vergleiche sie mit dem Operator==, um deine benutzerdefinierte Gleichheitslogik in Aktion zu sehen.
Deine Product-Klasse sollte Folgendes enthalten:
- Einen Konstruktor
:new(sku, name) - Eine Methode
:getInfo(), die eine Zeichenkette im Format[sku]: [name]zurückgibt - Die Metamethode
__eq, die Produkte anhand ihrer SKU vergleicht
Du erhältst sechs Eingaben:
- SKU des ersten Produkts
- Name des ersten Produkts
- SKU des zweiten Produkts
- Name des zweiten Produkts
- SKU des dritten Produkts
- Name des dritten Produkts
Erstelle in deiner Hauptdatei mithilfe der bereitgestellten Eingaben drei Produkte und gib anschließend Folgendes aus:
- Die Informationen zu jedem Produkt (drei Zeilen)
- Das Ergebnis des Vergleichs von Produkt 1 mit Produkt 2
- Das Ergebnis des Vergleichs von Produkt 1 mit Produkt 3
Wenn die Eingaben beispielsweise ABC123, Wireless Mouse, ABC123, Mouse (Updated), XYZ789 und Keyboard lauten, sollte die Ausgabe wie folgt aussehen:
ABC123: Wireless Mouse
ABC123: Mouse (Updated)
XYZ789: Keyboard
true
falseBeachte, dass die ersten beiden Produkte gleich sind (dieselbe SKU), obwohl sich ihre Namen unterscheiden. Genau so verfolgen echte Bestandssysteme Produkte trotz Namensänderungen und Aktualisierungen!
Probier es selbst
-- Das Product-Modul laden
local Product = require('Product')
-- Eingaben lesen
local sku1 = io.read()
local name1 = io.read()
local sku2 = io.read()
local name2 = io.read()
local sku3 = io.read()
local name3 = io.read()
-- TODO: Erstelle drei Product-Instanzen mit den Eingaben
-- TODO: Gib die Infos für jedes Produkt aus (drei Zeilen)
-- TODO: Gib das Ergebnis des Vergleichs von Produkt 1 mit Produkt 2 aus
-- TODO: Gib das Ergebnis des Vergleichs von Produkt 1 mit Produkt 3 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