Lua Academy · Les

Klassen via metatables

Simuleer klassen met tables en __index voor het opzoeken van methoden

Les 1 van 412 stappen

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 self

Velden 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  3

tostring 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))  -- false

Privé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 end

Klassen 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)              -- true

Meerdere 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  2

Snelle 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
Gratis beginnen

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

  1. Klassen via metatables
  2. Constructors en new()
  3. Instant methoden en self
  4. Inkapseling met closures
← Terug naar Lua Academy