Gleichheitsprüfungen
Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 17 von 70.
Sie haben gesehen, wie __tostring steuert, wie sich ein Objekt selbst anzeigt. Eine weitere nützliche Metamethode ist __eq, die definiert, wann zwei Objekte mit dem == Operator als gleich betrachtet werden sollten.
Standardmäßig prüft der Vergleich zweier Tabellen mit ==, ob es sich um genau dieselbe Tabelle im Speicher handelt. 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 (verschiedene Tabellen)Mit __eq kannst du deine eigene Gleichheitslogik definieren. In einer Klasse fügst du sie genau wie __tostring hinzu – als eine Funktion in der Klassentabelle. Damit die Gleichheitsprüfung funktioniert, müssen beide Objekte dieselbe Metatabelle teilen:
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 werden zwei User-Objekte als gleich betrachtet, 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 (unterschiedliche IDs)Dieses Muster ist wertvoll, wenn Objekte reale Entitäten mit eindeutigen Identifikatoren darstellen – beim Vergleich von Datenbankdatensätzen, Spielentitäten oder allen Objekten, bei denen die Identität wichtiger ist als der Speicherort.
Aufgabe
EinfachLassen Sie uns eine Product-Klasse erstellen, die feststellen kann, ob zwei Produkte derselbe Artikel sind – selbst wenn sie in völlig unterschiedlichen Tabellen gespeichert sind! In Einzelhandelssystemen haben Produkte oft eindeutige SKU-Codes (Stock Keeping Units), und zwei Produkte sollten als gleich betrachtet werden, wenn sie dieselbe SKU teilen, unabhängig von anderen Details wie Preisänderungen.
Sie werden Ihren Code auf zwei Dateien verteilen:
Product.lua: Definieren Sie IhreProduct-Klasse mit dem Standard-Prototyp-Muster. Jedes Produkt sollte einesku(die eindeutige Kennung) und einennamespeichern. Implementieren Sie 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: Binden Sie Ihr Product-Modul ein und erstellen Sie mehrere Produktinstanzen. Vergleichen Sie diese mit dem Operator==, um Ihre benutzerdefinierte Gleichheitslogik in Aktion zu sehen.
Ihre Product-Klasse sollte Folgendes enthalten:
- Einen
:new(sku, name)Konstruktor - Eine
:getInfo()Methode, die einen String im Format[sku]: [name]zurückgibt - Die Metamethode
__eq, die Produkte anhand ihrer SKU vergleicht
Sie erhalten sechs Eingaben:
- SKU für das erste Produkt
- Name für das erste Produkt
- SKU für das zweite Produkt
- Name für das zweite Produkt
- SKU für das dritte Produkt
- Name für das dritte Produkt
Erstellen Sie in Ihrer Hauptdatei drei Produkte mit den bereitgestellten Eingaben und geben Sie dann Folgendes aus:
- Die Informationen für jedes 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 sind, sollte die Ausgabe wie folgt aussehen:
ABC123: Wireless Mouse
ABC123: Mouse (Updated)
XYZ789: Keyboard
true
falseBeachten Sie, dass die ersten beiden Produkte gleich sind (gleiche SKU), obwohl sich ihre Namen unterscheiden – genau so verfolgen echte Inventarsysteme Produkte durch Namensänderungen und Aktualisierungen!
Spickzettel
Die Metamethode __eq definiert eine benutzerdefinierte Gleichheitslogik für Objekte, die den Operator == verwenden.
Standardmäßig prüft der Vergleich zweier Tabellen, ob es sich um dieselbe Tabelle im Speicher handelt:
local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2) -- Output: false (verschiedene Tabellen)Um eine benutzerdefinierte Gleichheit zu definieren, fügen Sie __eq als Funktion in der Klassentabelle hinzu. Beide Objekte müssen dieselbe Metatabelle teilen:
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
endJetzt sind Objekte basierend auf Ihrer benutzerdefinierten Logik gleich:
local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")
print(u1 == u2) -- Output: true (gleiche ID)
print(u1 == u3) -- Output: false (verschiedene IDs)Probier es selbst
-- Das Product-Modul einbinden
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: Drei Product-Instanzen unter Verwendung der Eingaben erstellen
-- TODO: Die Informationen für jedes Produkt ausgeben (drei Zeilen)
-- TODO: Das Ergebnis des Vergleichs von Produkt 1 mit Produkt 2 ausgeben
-- TODO: Das Ergebnis des Vergleichs von Produkt 1 mit Produkt 3 ausgeben
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
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-Klasse2Klassen-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