Instanzmethoden und self
Definieren Sie Methoden mit der Doppelpunkt-Syntax und dem impliziten Parameter self
Instanzmethoden und self ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 3 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.
self ist die Instanz
Wenn Sie obj:method() aufrufen, übergibt Lua obj automatisch als erstes Argument. Üblicherweise wird dieser Parameter self genannt. Über self greift die Methode auf Instanzdaten zu und ruft andere Methoden auf.
local Counter = {}
Counter.__index = Counter
function Counter.new(start)
return setmetatable({value=start or 0, step=1}, Counter)
end
function Counter:increment()
self.value = self.value + self.step
end
function Counter:getValue() return self.value end
local c = Counter.new(10)
c:increment(); c:increment()
print(c:getValue()) -- 12Method Chaining
Geben Sie aus Methoden self zurück, um Chaining zu ermöglichen: obj:method1():method2():method3(). Jeder Aufruf gibt dasselbe Objekt zurück und ermöglicht dadurch einen fluenten Stil. Das funktioniert am besten bei Methoden, die den Zustand ändern.
local Builder = {}
Builder.__index = Builder
function Builder.new()
return setmetatable({parts={}},Builder)
end
function Builder:add(s) self.parts[#self.parts+1]=s; return self end
function Builder:addAll(t)
for _,v in ipairs(t) do self.parts[#self.parts+1]=v end
return self
end
function Builder:build() return table.concat(self.parts," ") end
local result = Builder.new()
:add("Hello")
:add("from")
:addAll({"Lua","OOP"})
:build()
print(result) -- Hello from Lua OOPAndere Methoden aufrufen
Methoden können über self:otherMethod() andere Methoden derselben Instanz aufrufen. Das fördert die Wiederverwendung von Code innerhalb einer Klasse. Private Hilfsfunktionen können einfache lokale Funktionen sein, die self explizit erhalten.
local Stack = {}
Stack.__index = Stack
function Stack.new() return setmetatable({_data={},_size=0},Stack) end
function Stack:push(v) self._size=self._size+1; self._data[self._size]=v end
function Stack:pop()
if self:isEmpty() then return nil end
local v=self._data[self._size]; self._data[self._size]=nil
self._size=self._size-1; return v
end
function Stack:peek()
return not self:isEmpty() and self._data[self._size] or nil
end
function Stack:isEmpty() return self._size==0 end
function Stack:size() return self._size end
local s=Stack.new(); s:push(1);s:push(2);s:push(3)
print(s:pop(),s:peek(),s:size()) -- 3 2 2Warnung beim Überschreiben von Methoden
Wenn Sie ein Instanzfeld mit demselben Namen wie eine Klassenmethode setzen, überschattet dieses Feld die Methode für diese Instanz. Das ist meistens ein Fehler — seien Sie vorsichtig, wenn die Namen von Instanzfeldern mit Methodennamen kollidieren könnten.
local Dog = {}
Dog.__index = Dog
function Dog.new(n) return setmetatable({name=n},Dog) end
function Dog:speak() print(self.name..": Woof!") end
local d = Dog.new("Rex")
d:speak() -- Rex: Woof!
-- Accidental shadow:
d.speak = "loud" -- now d.speak is a string, not a function
local ok,err = pcall(function() d:speak() end)
print(ok, err) -- false attempt to call a string valueself in Callbacks
Wenn Sie eine Methode als Callback übergeben, geht das implizite self verloren. Umschließen Sie die Methode in einer Closure, um self zu erfassen.
local Timer = {}
Timer.__index = Timer
function Timer.new(n) return setmetatable({count=n},Timer) end
function Timer:tick()
self.count=self.count-1
print("Ticking, count:", self.count)
end
local t = Timer.new(3)
-- Wrong: loses self
-- local cb = t.tick -- cb(t) works but cb() doesn't
-- Correct: closure captures self
local cb = function() t:tick() end
cb(); cb(); cb() -- Ticking 3 timesStatische und Instanzmethoden
Eine statische Methode wird auf der Klasse und nicht auf einer Instanz aufgerufen. Sie besitzt kein self (oder erhält die Klasse als self). In Lua gibt es keinen formalen Unterschied — verwenden Sie konventionsgemäß . (nicht :) für statische Methoden.
local MathUtils = {}
MathUtils.__index = MathUtils
-- Static method (no instance needed)
function MathUtils.clamp(v, lo, hi)
return math.max(lo, math.min(hi, v))
end
-- Instance method (needs self)
function MathUtils:scale(factor)
self.value = self.value * factor
end
print(MathUtils.clamp(15, 0, 10)) -- 10
local m = setmetatable({value=5},MathUtils)
m:scale(3)
print(m.value) -- 15Mixin-Methoden
Fügen Sie Methoden aus einer Mixin-Tabelle zu einer Klasse hinzu, ohne formale Vererbung zu verwenden. Dies ist flache Komposition: Kopieren oder referenzieren Sie die Funktionen des Mixins in der Klassentabelle.
local Serializable = {}
function Serializable:serialize()
local parts={}
for k,v in pairs(self) do
if type(v)~="function" then
parts[#parts+1]=k.."="..tostring(v)
end
end
return "{"..table.concat(parts,",").."}"
end
local User = {}
User.__index = User
User.serialize = Serializable.serialize -- mixin!
function User.new(n,a) return setmetatable({name=n,age=a},User) end
local u = User.new("Alice",30)
print(u:serialize())Abstrakte Methoden
Lua erzwingt keine abstrakten Methoden. Sie können jedoch eine Klassenmethode der Basisklasse definieren, die einen Fehler auslöst und Unterklassen dazu zwingt, sie zu überschreiben. Dies ist eine Konvention für „muss überschrieben werden“.
local Shape = {}
Shape.__index = Shape
function Shape.new() return setmetatable({},Shape) end
function Shape:area()
error(type(self).." must implement area()",2)
end
function Shape:describe()
print("Shape area:", self:area())
end
local sq={}
setmetatable(sq,{__index=Shape})
function sq:area() return 4*4 end
sq:describe() -- Shape area: 16Methodentabellen
Bei Klassen mit vielen Methoden sollten Sie diese nach Funktionalität gruppieren. Alle Methoden in derselben Tabelle verwenden dieselbe Metatabellenauflösung, aber Sie können sie mithilfe von Sub-Namespaces nach Zuständigkeiten aufteilen.
local Entity = {}
Entity.__index = Entity
Entity.Physics = {}
function Entity.Physics:applyForce(fx,fy)
self.vx=(self.vx or 0)+fx
self.vy=(self.vy or 0)+fy
end
Entity.Render = {}
function Entity.Render:draw()
print(string.format("Draw at (%g,%g)",self.x or 0,self.y or 0))
end
-- Mix into main class
for k,v in pairs(Entity.Physics) do Entity[k]=v end
for k,v in pairs(Entity.Render) do Entity[k]=v end
function Entity.new(x,y) return setmetatable({x=x,y=y},Entity) end
local e=Entity.new(10,20); e:draw(); e:applyForce(5,0); print(e.vx)Delegation statt Vererbung
Bevorzugen Sie Delegation (das Halten einer Referenz) gegenüber tiefen Vererbungshierarchien. Eine Klasse kann Aufgaben an ein anderes Objekt delegieren, statt von ihm zu erben. So bleiben die Kopplung gering und die Zuständigkeit jeder Klasse klar.
local Logger = {}
Logger.__index = Logger
function Logger.new(name) return setmetatable({name=name},Logger) end
function Logger:log(msg) print("["..self.name.."] "..msg) end
local Service = {}
Service.__index = Service
function Service.new(name)
return setmetatable({
name=name,
logger=Logger.new(name) -- delegation
},Service)
end
function Service:start()
self.logger:log("starting...") -- delegate logging
print(self.name, "running")
end
Service.new("AuthService"):start()Kurztest
Was ist der Unterschied zwischen obj:method() und obj.method()?
Zusammenfassung: Instanzmethoden
Zusammenfassung:
- Doppelpunkt-Syntax beim Aufruf:
obj:method()==obj.method(obj) - Geben Sie self für Method Chaining zurück
- Andere Methoden aufrufen:
self:otherMethod() - Callbacks: Verwenden Sie eine Closure, um self zu erhalten
- Statische Methoden: Verwenden Sie konventionsgemäß die Punktnotation
- Delegation statt tiefer Vererbung für mehr Flexibilität
Häufig gestellte Fragen
Ist die Lektion „Instanzmethoden und self“ kostenlos?
Ja — der vollständige Text von „Instanzmethoden und self“ 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 „Instanzmethoden und self“?
Definieren Sie Methoden mit der Doppelpunkt-Syntax und dem impliziten Parameter self 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 3 von 4.
Wie lange dauert die Lektion „Instanzmethoden und self“?
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