Metodi delle istanze e self
Definisca metodi usando la sintassi con i due punti e il parametro implicito self.
Metodi delle istanze e self è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.
self è l'istanza
Quando chiama obj:method(), Lua passa automaticamente obj come primo argomento. Per convenzione, questo parametro si chiama self. Tramite self, il metodo accede ai dati dell'istanza e chiama altri metodi.
local Counter = {}
Counter.__index = Counter
function Counter.new(start)
return setmetatable({value=start or 0, step=1}, Counter)
end
function Counter:increment()
self.value = self.value + self.step
end
function Counter:getValue() return self.value end
local c = Counter.new(10)
c:increment(); c:increment()
print(c:getValue()) -- 12Concatenamento dei metodi
Restituisca self dai metodi per consentire il concatenamento: obj:method1():method2():method3(). Ogni chiamata restituisce lo stesso oggetto, consentendo uno stile fluente. Questo funziona al meglio per i metodi che modificano lo stato.
local Builder = {}
Builder.__index = Builder
function Builder.new()
return setmetatable({parts={}},Builder)
end
function Builder:add(s) self.parts[#self.parts+1]=s; return self end
function Builder:addAll(t)
for _,v in ipairs(t) do self.parts[#self.parts+1]=v end
return self
end
function Builder:build() return table.concat(self.parts," ") end
local result = Builder.new()
:add("Hello")
:add("from")
:addAll({"Lua","OOP"})
:build()
print(result) -- Hello from Lua OOPChiamare altri metodi
I metodi possono chiamare altri metodi sulla stessa istanza tramite self:otherMethod(). Questo favorisce il riutilizzo del codice all'interno di una classe. Gli helper privati possono essere semplici funzioni local che ricevono esplicitamente self.
local Stack = {}
Stack.__index = Stack
function Stack.new() return setmetatable({_data={},_size=0},Stack) end
function Stack:push(v) self._size=self._size+1; self._data[self._size]=v end
function Stack:pop()
if self:isEmpty() then return nil end
local v=self._data[self._size]; self._data[self._size]=nil
self._size=self._size-1; return v
end
function Stack:peek()
return not self:isEmpty() and self._data[self._size] or nil
end
function Stack:isEmpty() return self._size==0 end
function Stack:size() return self._size end
local s=Stack.new(); s:push(1);s:push(2);s:push(3)
print(s:pop(),s:peek(),s:size()) -- 3 2 2Avvertenza sulla sovrascrittura dei metodi
Impostare un campo dell'istanza con lo stesso nome di un metodo della classe nasconde il metodo per quell'istanza. Di solito è un bug: presti attenzione quando i nomi dei campi dell'istanza possono entrare in conflitto con quelli dei metodi.
local Dog = {}
Dog.__index = Dog
function Dog.new(n) return setmetatable({name=n},Dog) end
function Dog:speak() print(self.name..": Woof!") end
local d = Dog.new("Rex")
d:speak() -- Rex: Woof!
-- Accidental shadow:
d.speak = "loud" -- now d.speak is a string, not a function
local ok,err = pcall(function() d:speak() end)
print(ok, err) -- false attempt to call a string valueSelf nelle callback
Passare un metodo come callback fa perdere il self implicito. Racchiuda il metodo in una closure per catturare self.
local Timer = {}
Timer.__index = Timer
function Timer.new(n) return setmetatable({count=n},Timer) end
function Timer:tick()
self.count=self.count-1
print("Ticking, count:", self.count)
end
local t = Timer.new(3)
-- Wrong: loses self
-- local cb = t.tick -- cb(t) works but cb() doesn't
-- Correct: closure captures self
local cb = function() t:tick() end
cb(); cb(); cb() -- Ticking 3 timesMetodi statici e di istanza
Un metodo statico viene chiamato sulla classe, non su un'istanza. Non ha self (oppure riceve la classe come self). In Lua non esiste una distinzione formale: per convenzione, utilizzi . (non :) per i metodi statici.
local MathUtils = {}
MathUtils.__index = MathUtils
-- Static method (no instance needed)
function MathUtils.clamp(v, lo, hi)
return math.max(lo, math.min(hi, v))
end
-- Instance method (needs self)
function MathUtils:scale(factor)
self.value = self.value * factor
end
print(MathUtils.clamp(15, 0, 10)) -- 10
local m = setmetatable({value=5},MathUtils)
m:scale(3)
print(m.value) -- 15Metodi mixin
Aggiunga i metodi di una tabella mixin a una classe senza un'ereditarietà formale. Questa è una composizione piatta: copi o referenzi le funzioni del mixin nella tabella della classe.
local Serializable = {}
function Serializable:serialize()
local parts={}
for k,v in pairs(self) do
if type(v)~="function" then
parts[#parts+1]=k.."="..tostring(v)
end
end
return "{"..table.concat(parts,",").."}"
end
local User = {}
User.__index = User
User.serialize = Serializable.serialize -- mixin!
function User.new(n,a) return setmetatable({name=n,age=a},User) end
local u = User.new("Alice",30)
print(u:serialize())Metodi astratti
Lua non impone i metodi astratti, ma può definire un metodo della classe base che genera un errore, obbligando le sottoclassi a sovrascriverlo. È una convenzione per indicare che il metodo "deve essere sovrascritto".
local Shape = {}
Shape.__index = Shape
function Shape.new() return setmetatable({},Shape) end
function Shape:area()
error(type(self).." must implement area()",2)
end
function Shape:describe()
print("Shape area:", self:area())
end
local sq={}
setmetatable(sq,{__index=Shape})
function sq:area() return 4*4 end
sq:describe() -- Shape area: 16Tabelle dei metodi
Per le classi con molti metodi, li organizzi in gruppi in base alla funzionalità. Tutti i metodi nella stessa tabella condividono la stessa ricerca nella metatabella, ma può suddividerli per responsabilità utilizzando sottospazi dei nomi.
local Entity = {}
Entity.__index = Entity
Entity.Physics = {}
function Entity.Physics:applyForce(fx,fy)
self.vx=(self.vx or 0)+fx
self.vy=(self.vy or 0)+fy
end
Entity.Render = {}
function Entity.Render:draw()
print(string.format("Draw at (%g,%g)",self.x or 0,self.y or 0))
end
-- Mix into main class
for k,v in pairs(Entity.Physics) do Entity[k]=v end
for k,v in pairs(Entity.Render) do Entity[k]=v end
function Entity.new(x,y) return setmetatable({x=x,y=y},Entity) end
local e=Entity.new(10,20); e:draw(); e:applyForce(5,0); print(e.vx)Delegazione ed ereditarietà
Preferisca la delegazione (mantenere un riferimento) a catene di ereditarietà profonde. Una classe può delegare a un altro oggetto invece di ereditarne, mantenendo basso l'accoppiamento e concentrando ogni classe sul proprio compito.
local Logger = {}
Logger.__index = Logger
function Logger.new(name) return setmetatable({name=name},Logger) end
function Logger:log(msg) print("["..self.name.."] "..msg) end
local Service = {}
Service.__index = Service
function Service.new(name)
return setmetatable({
name=name,
logger=Logger.new(name) -- delegation
},Service)
end
function Service:start()
self.logger:log("starting...") -- delegate logging
print(self.name, "running")
end
Service.new("AuthService"):start()Verifica rapida
Qual è la differenza tra obj:method() e obj.method()?
Riepilogo: metodi di istanza
Riepilogo:
- Sintassi di chiamata con i due punti:
obj:method()==obj.method(obj) - Restituisca self per concatenare i metodi
- Chiami altri metodi:
self:otherMethod() - Callback: le racchiuda in una closure per preservare self
- Metodi statici: utilizzi per convenzione la notazione con il punto
- Preferisca la delegazione all'ereditarietà profonda per una maggiore flessibilità
Domande Frequenti
La lezione «Metodi delle istanze e self» è gratuita?
Sì — il testo completo di «Metodi delle istanze e self» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.
Cosa imparerò in «Metodi delle istanze e self»?
Definisca metodi usando la sintassi con i due punti e il parametro implicito self. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Lua Academy?
Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Metodi delle istanze e self»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Lua Academy?
Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Classi tramite metatabelle
- Costruttori e new()
- Metodi delle istanze e self
- Incapsulamento con le closure