Methoden überschreiben
Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 37 von 70.
Bisher haben Kindklassen Methoden der Elternklasse geerbt und neue hinzugefügt. Aber was ist, wenn eine Kindklasse den gleichen Methodennamen mit anderem Verhalten benötigt? Dies wird als Method Overriding bezeichnet.
Wenn Sie eine Methode in einer untergeordneten Klasse mit demselben Namen wie in der übergeordneten Klasse definieren, hat die Version der untergeordneten Klasse Vorrang. Die Lookup-Chain von Lua prüft zuerst die untergeordnete Klasse – wenn sie die Methode dort findet, hört sie auf zu suchen.
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:speak()
print(self.name .. " makes a sound")
end
-- Dog überschreibt speak()
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
function Dog:speak()
print(self.name .. " barks: Woof!")
endNun reagiert jede Klasse unterschiedlich auf denselben Methodenaufruf:
local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")
generic:speak() -- Ausgabe: Creature makes a sound
buddy:speak() -- Ausgabe: Buddy barks: Woof!Die :speak()-Methode von Dog ersetzt die Version der Elternklasse für Dog-Instanzen vollständig. Dies ermöglicht es Ihnen, spezialisiertes Verhalten zu erstellen und gleichzeitig ein konsistentes Interface beizubehalten – jedes Tier kann :speak() ausführen, aber jede Spezies tut dies auf unterschiedliche Weise.
Aufgabe
EinfachLass uns ein kleines Tierreich erschaffen, in dem verschiedene Kreaturen auf ihre eigene, einzigartige Weise sprechen! Du wirst eine Basisklasse Animal und zwei Kindklassen — Cat und Cow — erstellen, die jeweils die :speak()-Methode der Elternklasse mit ihrem eigenen spezialisierten Verhalten überschreiben.
Du wirst deinen Code auf vier Dateien verteilen:
Animal.lua: Deine Basisklasse mit einem:new(name)-Konstruktor, der den Namen des Tieres speichert. Füge eine:speak()-Methode hinzu, die den Namen des Tieres gefolgt vonmakes a soundausgibt. Dies ist das Standardverhalten, das die Kindklassen überschreiben werden.Cat.lua: Eine Kindklasse, die von Animal erbt. Ihr:new(name)-Konstruktor sollte den Eltern-Konstruktor aufrufen und dann die Metatabelle wieder mit Cat verknüpfen. Überschreibe die:speak()-Methode, damit Katzen etwas anderes sagen — gib den Namen der Katze gefolgt vonmeows: Meow!aus.Cow.lua: Eine weitere Kindklasse, die von Animal erbt. Richte den Konstruktor genauso ein wie bei Cat. Überschreibe:speak(), sodass Kühe ihren Namen gefolgt vonmoos: Moo!ausgeben.main.lua: Bring alles zusammen! Lies zwei Namen aus der Eingabe ein, erstelle eine Cat mit dem ersten Namen und eine Cow mit dem zweiten Namen. Rufe dann:speak()für beide auf, um zu demonstrieren, dass derselbe Methodenname je nach Klasse unterschiedliche Ausgaben erzeugt.
Du erhältst zwei Eingaben:
- Der Name der Katze
- Der Name der Kuh
Erstelle in deiner Hauptdatei beide Tiere und rufe :speak() zuerst für die Katze und dann für die Kuh auf.
Wenn die Eingaben zum Beispiel Whiskers und Bessie sind, sollte die Ausgabe wie folgt aussehen:
Whiskers meows: Meow!
Bessie moos: Moo!Beachte, wie beide Tiere auf denselben :speak()-Methodenaufruf reagieren, aber jedes eine für seinen Typ spezifische Ausgabe erzeugt. Die Version der Cat ersetzt das generische "makes a sound"-Verhalten der Elternklasse vollständig, ebenso wie die Version der Cow. Dies ist Methoden-Überschreibung (Method Overriding) in Aktion — gleiche Schnittstelle, unterschiedliche Implementierungen!
Spickzettel
Method Overriding ermöglicht es einer Kindklasse, eine Methode mit demselben Namen wie eine Elternmethode zu definieren und so das Verhalten der Elternklasse durch eine spezialisierte Funktionalität zu ersetzen.
Wenn Lua nach einer Methode sucht, prüft es zuerst die Kindklasse. Wenn es die Methode dort findet, verwendet es diese Version und beendet die Suche in der Elternklasse.
Grundlegendes Beispiel für Method Overriding:
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:speak()
print(self.name .. " makes a sound")
end
-- Dog überschreibt speak()
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
function Dog:speak()
print(self.name .. " barks: Woof!")
endVerwendung der überschriebenen Methode:
local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")
generic:speak() -- Ausgabe: Creature makes a sound
buddy:speak() -- Ausgabe: Buddy barks: Woof!Die Methode der Kindklasse ersetzt die Version der Elternklasse für Instanzen dieser Kindklasse vollständig, was spezialisiertes Verhalten ermöglicht, während eine konsistente Schnittstelle über alle Klassen hinweg beibehalten wird.
Probier es selbst
-- main.lua: Alles zusammenführen
local Cat = require('Cat')
local Cow = require('Cow')
-- Eingabe lesen
local catName = io.read()
local cowName = io.read()
-- TODO: Erstelle eine Katze mit dem ersten Namen
-- TODO: Erstelle eine Kuh mit dem zweiten Namen
-- TODO: Rufe zuerst :speak() für die Katze auf, dann für die Kuh
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
1Das 'self'-Konzept
Tabellen mit FunktionenExplizites 'self'Die Doppelpunkt-SyntaxPunkt vs. DoppelpunktZusammenfassung – Beweglicher Punkt4Projekt: Digitale Bank
Projekt-SetupEinzahlungsmethode7Polymorphie & Überschreiben
Methoden überschreibenElternmethoden aufrufenDuck TypingGemeinsames InterfaceTyp prüfenRückblick - Mitarbeiterrollen10Projekt: Formen-Manager
Projekt-SetupRechteck-Klasse2Klassen-Prototyp-Muster
Das Prototyp-KonzeptVerknüpfung mit __indexDer :new()-KonstruktorAttribute initialisierenUnabhängige InstanzenZusammenfassung – Autofabrik5Operatorüberladung in OOP
Objekte addierenObjekte subtrahierenObjekte verkettenObjekte vergleichen (<, >)Rückblick – Wallet-Mathematik3Objektzustand und -verhalten
InstanzvariablenGetter-MethodenSetter-MethodenBerechnete EigenschaftenStrings formatierenGleichheitsprüfungenZusammenfassung – Studentennote6Grundlagen der Vererbung
Das Vererbungs-SetupMethoden vererbenDen Konstruktor erweiternChild-Methoden hinzufügenGemeinsam vs. EinzigartigZusammenfassung - Formen-Hierarchie9Komposition & Mixins
Has-A-BeziehungDelegationEinfache MixinsAnwendung mehrerer MixinsMixins vs. VererbungZusammenfassung – Roboter-Montage12Abschluss-Herausforderungen
Wiederholung - InventarsystemWiederholung - BenutzerverwaltungWiederholung - Score-TrackerFinaler OOP-Check