Elternmethoden aufrufen
Teil des Abschnitts Objektorientierte Programmierung der Lua-Journey von Coddy. Lektion 38 von 70.
Manchmal ist es nicht das, was du möchtest, eine Methode vollständig zu überschreiben. Stattdessen möchtest du vielleicht das Verhalten der übergeordneten Klasse erweitern: das tun, was die übergeordnete Klasse tut, und anschließend etwas Zusätzliches hinzufügen. Dazu kannst du die Methode der übergeordneten Klasse direkt innerhalb der Überschreibung der Methode in der untergeordneten Klasse aufrufen.
Die Technik verwendet die Punkt-Syntax mit dem Namen der Elternklasse, wobei self explizit als erstes Argument übergeben wird:
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 erweitert das Verhalten der Elternklasse
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()
Animal.speak(self) -- Zuerst die Elternmethode aufrufen
print(self.name .. " wags tail happily")
endDie entscheidende Zeile ist Animal.speak(self). Indem wir die Punktsyntax für die übergeordnete Klasse verwenden und self manuell übergeben, rufen wir die ursprüngliche Methode auf, bevor wir unser eigenes Verhalten hinzufügen:
local buddy = Dog:new("Buddy")
buddy:speak()
-- Ausgabe:
-- Buddy macht ein Geräusch
-- Buddy wedelt glücklich mit dem SchwanzDieses Muster ist nützlich, wenn die übergeordnete Methode wichtige Aufgaben ausführt, die du nicht duplizieren möchtest. Die untergeordnete Methode kann die Logik der übergeordneten Methode zuerst, zuletzt oder sogar in der Mitte ihres eigenen Codes ausführen, sodass du die volle Kontrolle darüber hast, wie sich die Verhaltensweisen kombinieren.
Aufgabe
EinfachErstellen wir ein Begrüßungssystem, in dem ein FormalPerson das Verhalten einer regulären Person erweitert! Anstatt vollständig zu ersetzen, wie eine Person sich vorstellt, wird die formelle Version zuerst die standardmäßige Vorstellung ausführen und anschließend eine zusätzliche höfliche Geste hinzufügen.
Du wirst deinen Code auf drei Dateien verteilen:
Person.lua: Deine Basisklasse mit einem:new(name)-Konstruktor, der den Namen der Person speichert. Füge eine:introduce()-Methode ein, die den Namen der Person gefolgt vonsays hiausgibt. Dies ist das Basisverhalten, das erweitert werden soll.FormalPerson.lua: Eine Kindklasse, die von Person erbt. Ihr Konstruktor sollte den Konstruktor der übergeordneten Klasse aufrufen, um den Namen zu verarbeiten. Überschreibe die:introduce()-Methode, aber ersetze das Verhalten der übergeordneten Klasse nicht vollständig. Rufe stattdessen zuerst die Methode der übergeordneten Klasse mitPerson.introduce(self)auf und gib anschließend eine zusätzliche Zeile mit dem Namen der Person gefolgt vonbows politelyaus.main.lua: Fordere dein FormalPerson-Modul an, lies einen Namen von der Eingabe ein, erstelle eine FormalPerson-Instanz und rufe:introduce()auf, um beide kombinierten Verhaltensweisen zu sehen.
Du erhältst eine Eingabe: den Namen der Person.
Wenn du :introduce() für eine FormalPerson aufrufst, sollte dies zwei Ausgabezeilen erzeugen: die erste aus der Methode der übergeordneten Klasse, die zweite aus der Ergänzung der Kindklasse:
{name} says hi
{name} bows politelyWenn die Eingabe beispielsweise Eleanor lautet, sollte die Ausgabe folgendermaßen aussehen:
Eleanor says hi
Eleanor bows politelyDie wichtigste Erkenntnis ist, dass FormalPerson die Logik für „says hi“ nicht dupliziert. Stattdessen überträgt die Klasse diese Aufgabe an die Methode der übergeordneten Klasse und fügt anschließend ihr eigenes einzigartiges Verhalten hinzu. Dadurch bleibt dein Code übersichtlich und zeigt, wie Kindklassen die Funktionalität übergeordneter Klassen erweitern können, anstatt sie zu ersetzen!
Probier es selbst
-- main.lua: Einstiegspunkt für das Begrüßungssystem
local FormalPerson = require('FormalPerson')
-- Lies den Namen der Person von der Eingabe
local name = io.read()
-- TODO: Erstelle eine FormalPerson-Instanz mit dem gegebenen Namen
-- TODO: Rufe die introduce-Methode auf der FormalPerson-Instanz auf
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