Instansmetoder og self
Definér metoder med kolon-syntaks og den implicitte self-parameter.
Instansmetoder og self er en gratis Lua Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Lua Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Lua Academy-kurset indeholder 4 lektioner i alt.
self er instansen
Når du kalder obj:method(), sender Lua automatisk obj som det første argument. Efter konvention kaldes denne parameter self. Via self får metoden adgang til instansdata og kan kalde andre metoder.
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()) -- 12Metodekæder
Returnér self fra metoder for at aktivere kædning: obj:method1():method2():method3(). Hvert kald returnerer det samme objekt, så du kan skrive i en flydende stil. Det fungerer bedst for metoder, der ændrer tilstanden.
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 OOPKald af andre metoder
Metoder kan kalde andre metoder på den samme instans via self:otherMethod(). Det fremmer genbrug af kode i en klasse. Private hjælpefunktioner kan være almindelige lokale funktioner, der modtager self eksplicit.
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 2Advarsel om tilsidesættelse af metoder
Hvis du angiver et instansfelt med samme navn som en klassemetode, skjuler feltet metoden for den pågældende instans. Det er normalt en fejl — vær forsigtig, når navne på instansfelter kan kollidere med metoders navne.
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 i callbacks
Når du sender en metode som callback, går det implicitte self tabt. Pak metoden ind i en closure for at indfange 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 timesStatiske metoder og instansmetoder
En statisk metode kaldes på klassen, ikke på en instans. Den har ingen self (eller modtager klassen som self). I Lua er der ingen formel forskel — efter konvention bruger du . (ikke :) til statiske metoder.
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) -- 15Mixin-metoder
Tilføj metoder fra en mixin-tabel til en klasse uden formel nedarvning. Det er flad komposition: Kopiér eller referér til mixinens funktioner i klassetabellen.
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())Abstrakte metoder
Lua håndhæver ikke abstrakte metoder, men du kan definere en klassemetode i basisklassen, der udløser en fejl og tvinger underklasser til at tilsidesætte den. Det er en konvention for "skal tilsidesættes".
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: 16Metodetabeller
For klasser med mange metoder kan du organisere dem i grupper efter funktionalitet. Alle metoder i den samme tabel bruger det samme opslag via metatabellen, men du kan opdele dem efter ansvarsområde ved hjælp af undernavnerum.
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)Delegation kontra nedarvning
Foretræk delegation (at gemme en reference) frem for dybe nedarvningskæder. En klasse kan delegere til et andet objekt i stedet for at nedarve fra det, så koblingen forbliver løs, og hver klasse fokuserer på sit eget ansvar.
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()Hurtigt tjek
Hvad er forskellen på obj:method() og obj.method()?
Opsummering: Instansmetoder
Opsummering:
- Kolonkaldssyntaks:
obj:method()==obj.method(obj) - Returnér self for at kæde metoder
- Kald andre metoder:
self:otherMethod() - Callbacks: Pak dem ind i en closure for at bevare self
- Statiske metoder: Brug punktnotation efter konvention
- Foretræk delegation frem for dyb nedarvning for større fleksibilitet
Lær Lua med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 40
- Lektioner
- 159
Ofte stillede spørgsmål
Er lektionen “Instansmetoder og self” gratis?
Ja — alle 3 lektioner i læringssporet Lua Academy, inklusive “Instansmetoder og self”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Lua Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Instansmetoder og self”?
Definér metoder med kolon-syntaks og den implicitte self-parameter. Du øver dig i Lua Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Lua Academy?
Der kræves ingen tidligere erfaring. Lua Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “Instansmetoder og self”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Lua Academy-lektion?
Ja. Alle Lua Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Klasser via metatabeller
- Konstruktører og new()
- Instansmetoder og self
- Indkapsling med closures