0Pricing
Lua Academy · Lektion

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())  -- 12

Method 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 OOP

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

Warnung 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 value

self 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 times

Statische 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)  -- 15

Mixin-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: 16

Methodentabellen

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

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