Das Vererbungs-Setup
Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 31 von 70.
Bisher haben Sie Klassen erstellt, bei denen jedes Objekt Methoden in einer einzigen Prototyp-Tabelle nachschlägt. Aber was ist, wenn Sie möchten, dass eine Klasse auf einer anderen aufbaut? Hier kommt die Vererbung ins Spiel – eine Kindklasse kann auf alles von einer Elternklasse zugreifen und gleichzeitig eigene Funktionen hinzufügen.
Die entscheidende Erkenntnis ist, dass eine Klassentabelle selbst eine Metatabelle haben kann. Wenn Lua etwas in der Kindklasse nicht finden kann, schaut es im __index der Metatabelle des Kindes nach – welcher auf die Elternklasse verweist.
-- Basisklasse
local Animal = {}
Animal.__index = Animal
function Animal:new()
local obj = {}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print("Breathing...")
endHier ist nun der Vererbungsaufbau. Wir erstellen eine Kindklasse und setzen deren Metatabelle so, dass sie auf die Elternklasse schaut:
-- Kindklasse
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})Diese einzelne Zeile—setmetatable(Dog, {__index = Animal})—erzeugt die Vererbungshierarchie. Wenn eine Dog-Instanz eine Methode aufruft, die nicht in Dog gefunden wird, prüft Lua Animal.
Die Lookup-Kette funktioniert wie folgt: instance → Dog → Animal. Jeder Schritt verwendet __index, um die nächste zu durchsuchende Tabelle zu finden. Dies ermöglicht es Kindklassen, automatisch alle Methoden der Elternklasse zu erben, ohne diese kopieren zu müssen.
Aufgabe
EinfachLassen Sie uns Ihre erste Vererbungshierarchie aufbauen! Sie werden eine einfache Eltern-Kind-Klassenbeziehung erstellen, bei der eine Machine-Klasse als Basis dient und eine Robot-Klasse von ihr erbt.
Sie werden Ihren Code über drei Dateien organisieren:
Machine.lua: Definieren Sie Ihre Elternklasse mit dem Standard-Klassenmuster. Fügen Sie einen:new()-Konstruktor und eine:status()-Methode hinzu, dieMachine is operationalausgibt. Vergessen Sie nicht,__indexeinzurichten und die Klasse am Ende der Datei zurückzugeben.Robot.lua: Definieren Sie Ihre Kindklasse, die von Machine erbt. Binden Sie das Machine-Modul ein, richten Sie die Robot-Tabelle mit ihrem eigenen__indexein und stellen Sie die Vererbungsverbindung mitsetmetatable(Robot, {__index = Machine})her. Fügen Sie einen:new()-Konstruktor hinzu, der eine Instanz mit Robot als Metatabelle erstellt.main.lua: Führen Sie alles zusammen, indem Sie Ihr Robot-Modul einbinden, eine Robot-Instanz erstellen und die geerbte:status()-Methode aufrufen.
Das Schlüsselkonzept hierbei ist, dass Ihre Robot-Klasse :status() nicht selbst definiert – sie erbt diese Methode von Machine über die Metatabellen-Kette. Wenn Sie :status() auf einer Robot-Instanz aufrufen, sucht Lua zuerst in Robot, findet sie dort nicht und folgt dann dem __index-Link zu Machine, wo die Methode entdeckt wird.
Ihre Ausgabe sollte wie folgt aussehen:
Machine is operationalDiese einzelne Zeile beweist, dass die Vererbung funktioniert – Ihr Robot hat erfolgreich auf eine Methode zugegriffen, die nur in seiner Elternklasse definiert ist!
Spickzettel
Um Vererbung in Lua zu erstellen, setzen Sie die Metatabelle einer Klassentabelle so, dass sie mit __index auf die Elternklasse zeigt:
-- Elternklasse
local Animal = {}
Animal.__index = Animal
function Animal:new()
local obj = {}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print("Breathing...")
end
-- Kindklasse
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})Die Vererbungsverknüpfung wird mit setmetatable(Dog, {__index = Animal}) erstellt. Dies ermöglicht es Dog-Instanzen, automatisch auf Animal-Methoden zuzugreifen.
Die Suchkette folgt: Instanz → Kindklasse → Elternklasse. Jeder Schritt verwendet __index, um die nächste zu durchsuchende Tabelle zu finden.
Probier es selbst
-- main.lua: Alles zusammenführen
-- TODO: Das Robot-Modul anfordern
-- TODO: Eine Robot-Instanz mit Robot:new() erstellen
-- TODO: Die geerbte Methode :status() auf deiner Robot-Instanz aufrufen
-- Dies sollte "Machine is operational" ausgeben
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