Controlli di uguaglianza
Fa parte della sezione Programmazione orientata agli oggetti del percorso Lua di Coddy. Lezione 17 di 70.
Hai visto come __tostring controlla il modo in cui un oggetto viene visualizzato. Un altro metametodo utile è __eq, che definisce quando due oggetti devono essere considerati uguali usando l’operatore ==.
Per impostazione predefinita, confrontare due tabelle con == verifica se sono esattamente la stessa tabella in memoria. Due oggetti distinti con dati identici restituiranno false:
local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2) -- Output: false (tabelle diverse)Con __eq, puoi definire la tua logica di uguaglianza. In una classe, lo aggiungi proprio come __tostring, come funzione nella tabella della classe. Perché l'uguaglianza funzioni, entrambi gli oggetti devono condividere la stessa metatabella:
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
endOra due oggetti User sono considerati uguali se condividono lo stesso ID, indipendentemente dagli altri campi:
local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")
print(u1 == u2) -- Output: true (stesso ID)
print(u1 == u3) -- Output: false (ID diversi)Questo schema è utile quando gli oggetti rappresentano entità del mondo reale con identificatori univoci: confrontare record di database, entità di gioco o qualsiasi oggetto in cui l'identità conta più della posizione in memoria.
Sfida
FacileCostruiamo una classe Product in grado di determinare se due prodotti sono lo stesso articolo, anche quando sono archiviati in tabelle completamente diverse! Nei sistemi di vendita al dettaglio, i prodotti hanno spesso codici SKU univoci (Stock Keeping Unit) e due prodotti dovrebbero essere considerati uguali se hanno lo stesso SKU, indipendentemente da altri dettagli come le variazioni di prezzo.
Organizzerai il codice in due file:
Product.lua: definisci la classeProductcon il modello standard a prototipi. Ogni prodotto dovrebbe memorizzare unosku(l'identificatore univoco) e unname. Implementa il metametodo__eqin modo che due prodotti siano considerati uguali quando hanno lo stesso SKU: il nome non conta per stabilire l'uguaglianza.main.lua: importa il modulo Product e crea diverse istanze di prodotto. Confrontale usando l'operatore==per vedere in azione la logica di uguaglianza personalizzata.
La classe Product dovrebbe includere:
- Un costruttore
:new(sku, name) - Un metodo
:getInfo()che restituisce una stringa nel formato:[sku]: [name] - Il metametodo
__eqche confronta i prodotti in base al loro SKU
Riceverai sei input:
- SKU del primo prodotto
- Nome del primo prodotto
- SKU del secondo prodotto
- Nome del secondo prodotto
- SKU del terzo prodotto
- Nome del terzo prodotto
Nel file principale, crea tre prodotti usando gli input forniti, poi stampa:
- Le informazioni di ciascun prodotto (tre righe)
- Il risultato del confronto tra il prodotto 1 e il prodotto 2
- Il risultato del confronto tra il prodotto 1 e il prodotto 3
Ad esempio, se gli input sono ABC123, Wireless Mouse, ABC123, Mouse (Updated), XYZ789 e Keyboard, l'output dovrebbe essere:
ABC123: Wireless Mouse
ABC123: Mouse (Updated)
XYZ789: Keyboard
true
falseNota che i primi due prodotti sono uguali (stesso SKU), anche se i loro nomi sono diversi. È proprio così che i veri sistemi di gestione delle scorte tengono traccia dei prodotti quando i nomi cambiano e vengono aggiornati!
Provalo tu
-- Carica il modulo Product
local Product = require('Product')
-- Leggi gli input
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: Crea tre istanze di Product usando gli input
-- TODO: Stampa le informazioni di ciascun prodotto (tre righe)
-- TODO: Stampa il risultato del confronto tra il prodotto 1 e il prodotto 2
-- TODO: Stampa il risultato del confronto tra il prodotto 1 e il prodotto 3
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Il concetto di «self»
Tabelle con funzioni«self» esplicitoLa sintassi dei due puntiPunto o due puntiRiepilogo - Spostare il punto4Progetto: Banca digitale
Configurazione del progettoMetodo di deposito2Schema del prototipo di classe
Il concetto di prototipoCollegare con __indexIl costruttore :new()Inizializzare gli attributiIstanze indipendentiRiepilogo - Fabbrica di auto5Sovraccarico degli operatori nella OOP
Sommare oggettiSottrarre oggettiConcatenare oggettiConfrontare oggetti (<, >)Ripasso - Calcoli con il portafoglio8Incapsulamento
Convenzioni di denominazioneClosure per la privacyAccesso tramite closureTabelle di sola letturaLogica di convalidaRiepilogo - Cassaforte sicura11Modelli di progettazione (base)
Funzioni factoryTabella singletonPattern IteratorObserver (listener)Riepilogo - Factory per logger3Stato e comportamento degli oggetti
Variabili di istanzaMetodi getterMetodi setterProprietà calcolateFormattazione delle stringheControlli di uguaglianzaRiepilogo - Voto dello studente6Fondamenti dell'ereditarietà
Configurare l'ereditarietàEreditare i metodiEstendere il costruttoreAggiungere metodi alla classe figliaCondiviso vs specificoRiepilogo - Gerarchia delle formeEsercitati da solo: Compilatore Lua online