0Pricing
Lua Academy · Lektion

Überschreiben und Polymorphismus

Überschreiben Sie Methoden der Elternklasse und erreichen Sie polymorphe Aufrufe zur Laufzeit

Überschreiben und Polymorphismus ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 4 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.

Methodenüberschreibung

Eine Kindklasse überschreibt eine Methode der Elternklasse, indem sie eine Methode mit demselben Namen definiert. Wird sie für eine Instanz der Kindklasse aufgerufen, wird die Version der Kindklasse ausgeführt. Auf die Version der Elternklasse kann weiterhin über Parent.method(self) zugegriffen werden.

local Shape={} Shape.__index=Shape
function Shape:area() return 0 end
function Shape:describe() print(type(self).." area="..self:area()) end

local Circle={} Circle.__index=Circle
setmetatable(Circle,{__index=Shape})
function Circle.new(r) return setmetatable({r=r},Circle) end
function Circle:area() return math.pi*self.r^2 end

local Square={} Square.__index=Square
setmetatable(Square,{__index=Shape})
function Square.new(s) return setmetatable({s=s},Square) end
function Square:area() return self.s^2 end

Circle.new(5):describe()
Square.new(4):describe()

Polymorphes Dispatching

Polymorphie bedeutet, dass verschiedene Objekttypen unterschiedlich auf dieselbe Nachricht reagieren. Eine Funktion, die jede beliebige „Form“ akzeptiert und :area() aufruft, funktioniert mit jedem Formtyp – jeder Typ antwortet mit seiner eigenen Implementierung.

local shapes={
  Circle.new(3),
  Square.new(4),
  Circle.new(1),
}

local total=0
for _,shape in ipairs(shapes) do
  total=total+shape:area()
end
print(string.format("Total area: %.2f",total))

Duck-Typing

Lua verwendet Duck-Typing: Wenn ein Objekt über die Methode verfügt, funktioniert es. Eine formale Schnittstellendeklaration ist nicht erforderlich. Eine Funktion, die :speak() aufruft, funktioniert mit jedem Objekt, das eine speak-Methode besitzt, unabhängig von seiner Klasse.

local function makeNoise(obj)
  if type(obj.speak)=="function" then
    obj:speak()
  else
    print("(silent)")
  end
end

local Duck={speak=function(self) print("Quack!") end}
local Robot={speak=function(self) print("Beep boop!") end}
local Rock={}

makeNoise(Duck)   -- Quack!
makeNoise(Robot)  -- Beep boop!
makeNoise(Rock)   -- (silent)

Operator-Polymorphie

Metamethoden wie __add ermöglichen Polymorphie für Operatoren. Verschiedene Typen können unterschiedlich auf + reagieren, solange sie __add definieren.

local Vec2={} Vec2.__index=Vec2
Vec2.__add=function(a,b) return Vec2.new(a.x+b.x,a.y+b.y) end
Vec2.__tostring=function(v) return "("..v.x..","..v.y..")" end
function Vec2.new(x,y) return setmetatable({x=x,y=y},Vec2) end

local Color={} Color.__index=Color
Color.__add=function(a,b)
  return Color.new(math.min(255,a.r+b.r),math.min(255,a.g+b.g),math.min(255,a.b+b.b))
end
function Color.new(r,g,b) return setmetatable({r=r,g=g,b=b},Color) end

print(tostring(Vec2.new(1,2)+Vec2.new(3,4)))  -- (4,6)

Besuchermuster

Das Besuchermuster trennt Operationen von Objekten. Eine Operation „besucht“ Objekte verschiedener Typen und ruft abhängig vom Typ die passende Methode auf. Verwenden Sie es für Operationen, die je nach Typ variieren müssen, ohne die Typen zu ändern.

local function printInfo(obj)
  local mt = getmetatable(obj)
  if mt == Circle then
    print(string.format("Circle r=%.1f area=%.2f",obj.r,obj:area()))
  elseif mt == Square then
    print(string.format("Square s=%.1f area=%.2f",obj.s,obj:area()))
  end
end
for _,s in ipairs({Circle.new(3),Square.new(4)}) do
  printInfo(s)
end

Schnittstellentabelle

Definieren Sie eine Schnittstelle als Tabelle mit Methodennamen. Überprüfen Sie vor der polymorphen Verwendung, ob ein Objekt alle erforderlichen Methoden implementiert.

local function implements(obj, interface)
  for _, method in ipairs(interface) do
    if type(obj[method]) ~= "function" then
      return false, "missing: "..method
    end
  end
  return true
end

local Drawable = {"draw","resize","move"}

local Widget = {
  draw=function(self) print("draw "..self.type) end,
  resize=function(self,w,h) self.w,self.h=w,h end,
  move=function(self,x,y) self.x,self.y=x,y end,
  type="button"
}

local ok,err = implements(Widget,Drawable)
print(ok,err)  -- true nil

Prüfen, ob eine Methode existiert

Prüfen Sie vor dem polymorphen Aufruf einer optionalen Methode, ob das Objekt über diese Methode verfügt. So werden optionale Fähigkeiten ermöglicht, ohne eine gemeinsame Basisklasse vorauszusetzen.

local function maybeUpdate(obj, dt)
  if type(obj.update)=="function" then
    obj:update(dt)
  end
end

local objects={
  {x=0,y=0,update=function(self,dt) self.x=self.x+10*dt end},
  {x=0,y=0},  -- no update
  {x=0,y=0,update=function(self,dt) self.y=self.y+5*dt end},
}

for _,o in ipairs(objects) do maybeUpdate(o,1) end
for _,o in ipairs(objects) do print(o.x,o.y) end

Dispatch-Tabelle nach Typ

Verwenden Sie anstelle von if/elseif-Ketten eine Dispatch-Tabelle: Ordnen Sie Typnamen Handler-Funktionen zu. Dies ist das tabellengesteuerte Polymorphie-Muster.

local handlers={
  number  = function(v) return "num:"..v end,
  string  = function(v) return "str:\"".."..v.."\"" end,
  boolean = function(v) return "bool:"..(v and "T" or "F") end,
  table   = function(v) return "tbl:#"..tostring(#v) end,
}

local function describe(v)
  local h=handlers[type(v)]
  return h and h(v) or "unknown"
end

print(describe(42))
print(describe("hello"))
print(describe({1,2,3}))

Kovariante Rückgabewerte

Methoden von Kindklassen können spezifischere Typen zurückgeben als Methoden der Elternklasse (kovarianter Rückgabewert). Da Lua dynamisch typisiert ist, ergibt sich dies ganz natürlich – die Factory-Methode einer Kindklasse gibt eine Instanz der Kindklasse zurück, nicht nur der Elternklasse.

local Base={} Base.__index=Base
function Base.new() return setmetatable({type="base"},Base) end
function Base:copy() return Base.new() end

local Child={} Child.__index=Child
setmetatable(Child,{__index=Base})
function Child.new(extra)
  local self=setmetatable({type="child"},Child)
  self.extra=extra; return self
end
function Child:copy() return Child.new(self.extra) end  -- covariant

local c=Child.new("hello")
local c2=c:copy()
print(c2.extra,getmetatable(c2)==Child)  -- hello true

Zusammenfassung: Polymorphie

Polymorphie in Lua praktisch: Derselbe Methodenname führt je nach Typ zu unterschiedlichem Verhalten. Dies wird durch metatabellenbasiertes OOP, Duck-Typing-Prüfungen oder Dispatch-Tabellen erreicht. Es ist kein formales Schnittstellensystem erforderlich – nur einheitliche Konventionen für Methodennamen.

-- Three ways to achieve polymorphism:
-- 1. Metatable inheritance + method override
-- 2. Duck typing: just call it if it exists
-- 3. Dispatch table: map type -> handler

local function area(shape)
  -- Duck typing approach:
  assert(type(shape.area)=="function","needs area()")
  return shape:area()
end

print(area({area=function() return 16 end}))  -- 16

Polymorphie-Frage

Wie funktioniert Polymorphie in Lua?

Zusammenfassung: Überschreibung und Polymorphie

Überschreiben Sie Methoden der Elternklasse, indem Sie sie in der Kindklasse neu definieren. Lua löst Aufrufe entlang der __index-Kette von unten nach oben auf und erreicht so ganz natürlich polymorphes Dispatching zur Laufzeit.

Häufig gestellte Fragen

Ist die Lektion „Überschreiben und Polymorphismus“ kostenlos?

Ja — der vollständige Text von „Überschreiben und Polymorphismus“ 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 „Überschreiben und Polymorphismus“?

Überschreiben Sie Methoden der Elternklasse und erreichen Sie polymorphe Aufrufe zur Laufzeit 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 4 von 4.

Wie lange dauert die Lektion „Überschreiben und Polymorphismus“?

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. Einfache Vererbung mit __index-Verkettung
  2. Elternmethoden mit super aufrufen
  3. Mixin-Muster
  4. Überschreiben und Polymorphismus
← Zurück zu Lua Academy