Klassen über Metatabellen
Simulieren Sie Klassen mit Tabellen und __index für die Methodensuche
Klassen über Metatabellen ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Lua Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.
Muster mit Klassentabellen
In Lua ist eine „Klasse“ lediglich eine Tabelle, in der Methoden gespeichert werden. Instanzen sind Tabellen, deren Metatable mit __index auf die Klassentabelle verweist. Dadurch sind alle Methoden über die Suchkette auf den Instanzen verfügbar.
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 verweist auf die Klasse
Die Zuweisung ClassName.__index = ClassName bedeutet: „Suche fehlende Schlüssel in der Klassentabelle.“ Beim Aufruf einer Instanzmethode findet Lua die Methode nicht in der Instanz, prüft die Metatable (__index), findet die Klasse und sucht die Methode dort.
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)Konstruktor-Muster
Die Funktion new() ist der Konstruktor: Sie erstellt eine Tabelle mit Instanzdaten und gibt sie mit einer Metatable zurück, die auf die Klasse verweist. Dies ist die Standardmethode, um Objekte in Lua zu erstellen.
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()))Methoden- und Funktionssyntax
obj:method() ist eine Kurzschreibweise für obj.method(obj). Definieren Sie Methoden mit der Doppelpunkt-Syntax (function Cls:method()), damit self implizit übergeben wird. Rufen Sie die Methode ebenfalls mit einem Doppelpunkt auf, um die Instanz zu übergeben. Das Mischen von Punkt- und Doppelpunkt-Syntax führt zu schwer erkennbaren Fehlern.
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 selfFelder auf Klassen- und Instanzebene
Felder in der Klassentabelle werden von allen Instanzen gemeinsam verwendet (Klassenvariablen). Felder in der Instanztabelle gehören jeweils nur zu einer Instanz. Eine Instanz kann ein Klassenfeld überschreiben, indem sie ein eigenes Feld mit demselben Namen erstellt.
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 für Klassen
Fügen Sie der Klassentabelle __tostring hinzu, um eine lesbare Ausgabe beim Drucken zu erhalten. Da die Metatable der Instanz die Klasse ist und die Klasse über __tostring verfügt, verwenden alle Instanzen diese Funktion 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)Instanztyp prüfen
Prüfen Sie, ob ein Objekt eine Instanz einer Klasse ist, indem Sie seine Metatable mit der Klassentabelle vergleichen. Dies ist das Lua-Gegenstück zu 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 Methoden
Private Methoden sind lokale Funktionen in der Moduldatei. Sie können nicht von außerhalb aufgerufen werden, sind aber innerhalb der öffentlichen Methoden des Moduls als Upvalues verfügbar.
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 endKlassenvergleich
Überladen Sie __eq und __lt für benutzerdefinierte Gleichheits- und Vergleichsoperationen. Lua ruft __eq bei Tabellen nur auf, wenn beide Operanden dieselbe Metatable verwenden.
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) -- trueMehrere Klassen
Jede Klasse ist eine unabhängige Tabelle mit ihrer eigenen Metatable. Objekte aus unterschiedlichen Klassen haben unterschiedliche Metatables. Dies bildet die Grundlage für ein objektorientiertes System mit mehreren 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 2Schnelltest
Warum setzen wir ClassName.__index = ClassName?
Rückblick: Klassen über Metatables
Zusammenfassung:
- Klasse = Tabelle +
__index = self - Konstruktor:
function Cls.new(...) return setmetatable({}, Cls) end - Methoden: in der Klassentabelle definiert und mit der Doppelpunkt-Syntax aufgerufen
- Klassen- und Instanzfelder: Klassenfelder werden geteilt, Instanzfelder gehören jeweils zu einem Objekt
- Typprüfung:
getmetatable(obj) == Cls
Häufig gestellte Fragen
Ist die Lektion „Klassen über Metatabellen“ kostenlos?
Ja — der vollständige Text von „Klassen über Metatabellen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Lua Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Klassen über Metatabellen“?
Simulieren Sie Klassen mit Tabellen und __index für die Methodensuche Du übst Lua Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Lua Academy zu starten?
Keine Vorkenntnisse erforderlich. Lua Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Klassen über Metatabellen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Lua Academy-Lektion Code schreiben und ausführen?
Ja. Jede Lua Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Klassen über Metatabellen
- Konstruktoren und new()
- Instanzmethoden und self
- Kapselung mit Closures