0Pricing
Lua Academy · Lektion

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 self

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

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

Private 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 end

Klassenvergleich

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

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

Schnelltest

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

  1. Klassen über Metatabellen
  2. Konstruktoren und new()
  3. Instanzmethoden und self
  4. Kapselung mit Closures
← Zurück zu Lua Academy