Klassen via metatables
Simuleer klassen met tables en __index voor het opzoeken van methoden
Klassen via metatables is een gratis Lua Academy-les op CoddyKit. Dit is les 1 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Lua Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Lua Academy bevat in totaal 4 lessen.
Patroon met klassentabellen
In Lua is een "klasse" gewoon een tabel waarin methoden worden opgeslagen. Instanties zijn tabellen waarvan de metatabel via __index naar de klassentabel verwijst. Hierdoor zijn alle methoden via de opzoekketen toegankelijk op instanties.
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 verwijst naar de klasse
Als je ClassName.__index = ClassName instelt, betekent dit: "zoek ontbrekende sleutels op in de klassentabel". Wanneer een instantiemethode wordt aangeroepen, vindt Lua deze niet in de instantie, controleert het de metatabel (__index), vindt het de klasse en zoekt het de methode daar op.
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)Constructiepatroon
De functie new() is de constructor: deze maakt een tabel met instantiegegevens, verpakt die in een metatabel die naar de klasse verwijst en retourneert de tabel. Dit is de standaardmanier om objecten te maken in 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()))Syntaxis van methode versus functie
obj:method() is een verkorte schrijfwijze voor obj.method(obj). Definieer methoden met dubbelepuntsyntaxis (function Cls:method()) om impliciet self te krijgen. Roep ze aan met een dubbele punt om de instantie door te geven. Het combineren van punt- en dubbelepuntsyntaxis veroorzaakt subtiele fouten.
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 selfVelden op klasse- versus instantieniveau
Velden in de klassentabel worden gedeeld door alle instanties (klassevariabelen). Velden in de instantietabel gelden per instantie. Een instantie kan een klasseveld overschaduwen door een eigen veld met dezelfde naam te maken.
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 voor klassen
Voeg __tostring toe aan de klassentabel voor leesbare uitvoer bij het afdrukken. Omdat de metatabel van de instantie de klasse is en de klasse __tostring heeft, gebruiken alle instanties deze automatisch.
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)Type van instantie controleren
Controleer of een object een instantie van een klasse is door de metatabel ervan te vergelijken met de klassentabel. Dit is het Lua-equivalent van 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)) -- falsePrivémethoden
Privémethoden zijn lokale functies in het modulebestand. Ze kunnen niet van buitenaf worden aangeroepen, maar zijn binnen de openbare methoden van de module toegankelijk als 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 endKlassen vergelijken
Overschrijf __eq en __lt voor aangepaste gelijkheid en ordening. Lua roept __eq voor tabellen alleen aan wanneer beide operanden dezelfde metatabel delen.
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) -- trueMeerdere klassen
Elke klasse is een onafhankelijke tabel met een eigen metatabel. Objecten uit verschillende klassen hebben verschillende metatabellen. Dit vormt de basis voor een OOP-systeem met meerdere klassen in 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 2Snelle controle
Waarom stellen we ClassName.__index = ClassName in?
Samenvatting: klassen via metatabellen
Samenvatting:
- Klasse = tabel +
__index = self - Constructor:
function Cls.new(...) return setmetatable({}, Cls) end - Methoden: gedefinieerd in de klassentabel, aangeroepen met dubbelepuntsyntaxis
- Klasse- versus instantievelden: klassevelden worden gedeeld, instantievelden gelden per object
- Typecontrole:
getmetatable(obj) == Cls
Leer Lua met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 40
- Lessen
- 159
Veelgestelde vragen
Is de les “Klassen via metatables” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Lua Academy, waaronder “Klassen via metatables”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Lua Academy bevat in totaal 4 lessen.
Wat leer ik in “Klassen via metatables”?
Simuleer klassen met tables en __index voor het opzoeken van methoden Je oefent met Lua Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Lua Academy te beginnen?
Ervaring vooraf is niet nodig. Lua Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “Klassen via metatables”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Lua Academy?
Ja. Elke les over Lua Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Klassen via metatables
- Constructors en new()
- Instant methoden en self
- Inkapseling met closures