Methoden überschreiben
Teil des Abschnitts Objektorientierte Programmierung 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 denselben Methodennamen mit anderem Verhalten benötigt? Dies wird als Methodenüberschreibung bezeichnet.
Wenn du in einer untergeordneten Klasse eine Methode mit demselben Namen wie in der übergeordneten Klasse definierst, hat die Version der untergeordneten Klasse Vorrang. Luas Suchkette überprüft zuerst die untergeordnete Klasse. Wenn sie die Methode dort findet, beendet sie die Suche.
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!")
endJetzt reagiert jede Klasse unterschiedlich auf denselben Methodenaufruf:
local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")
generic:speak() -- Ausgabe: Creature macht ein Geräusch
buddy:speak() -- Ausgabe: Buddy bellt: Woof!:speak() von Dog ersetzt die Version des Elternobjekts für Dog-Instanzen vollständig. So kannst du spezielles Verhalten erstellen und gleichzeitig eine konsistente Schnittstelle beibehalten: Jedes Tier kann :speak() aufrufen, aber jede Tierart tut dies anders.
Aufgabe
EinfachLass uns ein kleines Tierreich aufbauen, in dem verschiedene Tiere auf ihre ganz eigene Weise sprechen! Du erstellst eine übergeordnete Klasse Animal und zwei untergeordnete Klassen, Cat und Cow, die jeweils die :speak()-Methode der übergeordneten Klasse mit ihrem eigenen speziellen Verhalten überschreiben.
Du organisierst deinen Code auf vier Dateien verteilt:
Animal.lua: Deine Basisklasse mit einem:new(name)-Konstruktor, der den Namen des Tiers speichert. Füge eine:speak()-Methode hinzu, die den Namen des Tiers gefolgt vonmakes a soundausgibt. Dies ist das Standardverhalten, das die untergeordneten Klassen überschreiben werden.Cat.lua: Eine untergeordnete Klasse, die von Animal erbt. Ihr:new(name)-Konstruktor sollte den Konstruktor der übergeordneten Klasse aufrufen und anschließend die Metatabelle wieder mit Cat verknüpfen. Überschreibe die:speak()-Methode, sodass Katzen etwas anderes sagen: Gib den Namen der Katze gefolgt vonmeows: Meow!aus.Cow.lua: Eine weitere untergeordnete Klasse, die von Animal erbt. Richte den Konstruktor genauso wie bei Cat ein. Überschreibe:speak(), sodass Kühe ihren Namen gefolgt vonmoos: Moo!ausgeben.main.lua: Führe alles zusammen! Lies zwei Namen aus der Eingabe ein, erstelle eine Cat mit dem ersten Namen und eine Cow mit dem zweiten Namen und rufe anschließend für beide:speak()auf, um zu zeigen, dass derselbe Methodenname je nach Klasse eine unterschiedliche Ausgabe erzeugt.
Du erhältst zwei Eingaben:
- Den Namen der Katze
- Den Namen der Kuh
Erstelle in deiner Hauptdatei beide Tiere und rufe zuerst für die Katze und anschließend für die Kuh :speak() auf.
Wenn die Eingaben beispielsweise Whiskers und Bessie lauten, sollte die Ausgabe folgendermaßen aussehen:
Whiskers meows: Meow!
Bessie moos: Moo!Beachte, wie beide Tiere auf denselben Aufruf der Methode :speak() reagieren, aber jedes eine für seinen Typ spezifische Ausgabe erzeugt. Die Version von Cat ersetzt das allgemeine Verhalten der übergeordneten Klasse, nämlich „makes a sound“, vollständig – und bei Cow ist es genauso. Das ist Methodenüberschreibung in Aktion: dieselbe Schnittstelle, unterschiedliche Implementierungen!
Probier es selbst
-- main.lua: Alles zusammenbringen
local Cat = require('Cat')
local Cow = require('Cow')
-- Eingabe lesen
local catName = io.read()
local cowName = io.read()
-- TODO: Erstelle eine Cat mit dem ersten Namen
-- TODO: Erstelle eine Cow mit dem zweiten Namen
-- TODO: Rufe :speak() zuerst auf der cat auf, dann auf der cow
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
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-KlasseKreis-KlasseUmfang-MethodeFormen-SammlungGesamtflächeFormen filtern2Klassen-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Übe selbstständig: Online-Lua-Compiler