Klasser via metatabeller
Simuler klasser ved hjelp av tabeller og __index for oppslag av metoder.
Klasser via metatabeller er en gratis leksjon i Lua Academy på CoddyKit. Dette er leksjon 1 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Lua Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Lua Academy inneholder totalt 4 leksjoner.
Klassetabellmønster
I Lua er en «klasse» bare en tabell som lagrer metoder. Instanser er tabeller der metatabellens __index peker på klassetabellen. Dermed blir alle metodene tilgjengelige på instansene via oppslagskjeden.
local Animal = {}
Animal.__index = Animal
function Animal.new(name, sound)
return setmetatable({name=name, sound=sound}, Animal)
end
function Animal:speak()
print(self.name .. " says " .. self.sound)
end
local dog = Animal.new("Rex","Woof")
dog:speak() -- Rex says Woof__index peker på klassen
Ved å angi ClassName.__index = ClassName betyr De «slå opp manglende nøkler i klassetabellen». Når en instansmetode kalles, finner ikke Lua metoden i instansen, kontrollerer metatabellen (__index), finner klassen og slår opp metoden der.
local Point = {}
Point.__index = Point
Point.type = "2D Point"
function Point.new(x,y)
return setmetatable({x=x,y=y}, Point)
end
function Point:magnitude()
return math.sqrt(self.x^2 + self.y^2)
end
local p = Point.new(3,4)
print(p:magnitude()) -- 5.0
print(p.type) -- 2D Point (from class)Konstruktørmønster
Funksjonen new() er konstruktøren: Den oppretter en tabell med instansdata og returnerer den pakket inn i en metatabell som peker på klassen. Dette er standardmåten å opprette objekter på i Lua.
local Circle = {}
Circle.__index = Circle
function Circle.new(cx, cy, radius)
assert(radius > 0, "radius must be positive")
return setmetatable({cx=cx, cy=cy, r=radius}, Circle)
end
function Circle:area()
return math.pi * self.r^2
end
function Circle:perimeter()
return 2 * math.pi * self.r
end
local c = Circle.new(0, 0, 5)
print(string.format("Area: %.2f", c:area()))Metode- kontra funksjonssyntaks
obj:method() er syntaktisk sukker for obj.method(obj). Definer metoder med kolon-syntaks (function Cls:method()) for å få en implisitt self. Kall med kolon for å sende instansen. Hvis De blander punktum og kolon, oppstår subtile feil.
local Dog = {}
Dog.__index = Dog
-- Define with colon: self is implicit
function Dog:bark(times)
for i = 1, (times or 1) do
print(self.name .. ": Woof!")
end
end
function Dog.new(name)
return setmetatable({name=name}, Dog)
end
local d = Dog.new("Buddy")
d:bark(2) -- Buddy: Woof! (x2)
-- Dog.bark(d,1) -- same thing, explicit selfFelter på klasse- og instansnivå
Felter i klassetabellen deles av alle instanser (klassevariabler). Felter i instanstabellen er spesifikke for hver instans. En instans kan skjule et klassefelt ved å opprette sitt eget felt med samme navn.
local Entity = {}
Entity.__index = Entity
Entity.count = 0 -- class-level counter
function Entity.new(name)
Entity.count = Entity.count + 1
return setmetatable({name=name, id=Entity.count}, Entity)
end
local a = Entity.new("alpha")
local b = Entity.new("beta")
local c = Entity.new("gamma")
print(Entity.count) -- 3
print(a.id, b.id, c.id) -- 1 2 3tostring for klasser
Legg til __tostring i klassetabellen for lesbar utskrift. Siden instansens metatabell er klassen, og klassen har __tostring, bruker alle instanser den automatisk.
local Vec2 = {}
Vec2.__index = Vec2
Vec2.__tostring = function(v)
return string.format("Vec2(%g, %g)", v.x, v.y)
end
function Vec2.new(x,y)
return setmetatable({x=x,y=y}, Vec2)
end
function Vec2.__add(a, b)
return Vec2.new(a.x+b.x, a.y+b.y)
end
local v1 = Vec2.new(1,2)
local v2 = Vec2.new(3,4)
print(v1+v2) -- Vec2(4, 6)Kontrollere instanstype
Kontroller om et objekt er en instans av en klasse ved å sammenligne metatabellen med klassetabellen. Dette er Lua-ekvivalenten til instanceof.
local Dog = {}
Dog.__index = Dog
function Dog.new(name)
return setmetatable({name=name}, Dog)
end
local function isDog(obj)
return getmetatable(obj) == Dog
end
local d = Dog.new("Rex")
local t = {}
print(isDog(d)) -- true
print(isDog(t)) -- falsePrivate metoder
Private metoder er lokale funksjoner i modulfila. De kan ikke kalles utenfra, men er tilgjengelige i modulens offentlige metoder som upvalues.
local Account = {}
Account.__index = Account
-- Private helper
local function validate(amount)
return type(amount)=="number" and amount > 0
end
function Account.new(balance)
return setmetatable({balance=balance or 0}, Account)
end
function Account:deposit(amount)
assert(validate(amount), "invalid amount")
self.balance = self.balance + amount
end
function Account:getBalance() return self.balance endKlassesammenligning
Overstyr __eq og __lt for egendefinert likhet og sortering. Lua kaller bare __eq for tabeller når begge operandene deler samme metatabell.
local Temp = {}
Temp.__index = Temp
Temp.__eq = function(a,b) return a.celsius == b.celsius end
Temp.__lt = function(a,b) return a.celsius < b.celsius end
Temp.__tostring = function(t)
return t.celsius.."°C"
end
function Temp.new(c)
return setmetatable({celsius=c}, Temp)
end
local t1 = Temp.new(100)
local t2 = Temp.new(0)
print(t1 == Temp.new(100)) -- true
print(t2 < t1) -- trueFlere klasser
Hver klasse er en uavhengig tabell med sin egen metatabell. Objekter fra forskjellige klasser har forskjellige metatabeller. Dette er grunnlaget for et OOP-system med flere klasser i Lua.
local Cat = {}
Cat.__index = Cat
function Cat.new(name) return setmetatable({name=name,lives=9},Cat) end
function Cat:loseLife() self.lives=self.lives-1; return self.lives end
local Dog2 = {}
Dog2.__index = Dog2
function Dog2.new(name) return setmetatable({name=name,tricks={}},Dog2) end
function Dog2:learn(t) self.tricks[#self.tricks+1]=t end
local c = Cat.new("Whiskers")
local d = Dog2.new("Buddy")
d:learn("sit"); d:learn("stay")
print(c:loseLife(), #d.tricks) -- 8 2Hurtigsjekk
Hvorfor angir vi ClassName.__index = ClassName?
Oppsummering: Klasser via metatabeller
Oppsummering:
- Klasse = tabell +
__index = self - Konstruktør:
function Cls.new(...) return setmetatable({}, Cls) end - Metoder: defineres i klassetabellen og kalles med kolon-syntaks
- Klasse- kontra instansfelter: Klassefelter deles, instansfelter er spesifikke for hvert objekt
- Typekontroll:
getmetatable(obj) == Cls
Lær deg Lua med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 40
- Leksjoner
- 159
Ofte stilte spørsmål
Er leksjonen «Klasser via metatabeller» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Lua Academy, inkludert «Klasser via metatabeller», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Lua Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Klasser via metatabeller»?
Simuler klasser ved hjelp av tabeller og __index for oppslag av metoder. Du øver på Lua Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Lua Academy?
Ingen tidligere erfaring er nødvendig. Lua Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.
Hvor lang tid tar leksjonen «Klasser via metatabeller»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Lua Academy-leksjonen?
Ja. Alle Lua Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Klasser via metatabeller
- Konstruktører og new()
- Instansmetoder og self
- Innkapsling med closures