Ü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)
endSchnittstellentabelle
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 nilPrü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) endDispatch-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 trueZusammenfassung: 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})) -- 16Polymorphie-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
- Einfache Vererbung mit __index-Verkettung
- Elternmethoden mit super aufrufen
- Mixin-Muster
- Überschreiben und Polymorphismus