Menu
Coddy logo textTech

Methoden vererben

Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 32 von 70.

Sobald die Vererbungsverbindung hergestellt ist, erhalten Instanzen der Kindklasse automatisch Zugriff auf alle Methoden der Elternklasse. Dies geschieht über die Lookup-Kette von Lua – wenn Sie eine Methode auf einer Instanz aufrufen, sucht Lua in jeder verbundenen Tabelle, bis es das findet, wonach Sie suchen.

Betrachten Sie diesen Aufbau, bei dem Animal eine :breathe()-Methode definiert:

local Animal = {}
Animal.__index = Animal

function Animal:new()
    local obj = {}
    setmetatable(obj, Animal)
    return obj
end

function Animal:breathe()
    print("Breathing...")
end

-- Dog erbt von Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new()
    local obj = {}
    setmetatable(obj, Dog)
    return obj
end

Beobachten Sie nun, was passiert, wenn wir ein Dog erstellen und die Methode der Elternklasse aufrufen:

local buddy = Dog:new()
buddy:breathe()  -- Ausgabe: Atmet...

Die Klasse Dog hat niemals :breathe() definiert, und dennoch funktioniert es. Lua prüft zuerst buddy, findet nichts, prüft dann Dog, immer noch nichts, und findet es schließlich in Animal. Diese automatische Methodenvererbung bedeutet, dass Sie gemeinsames Verhalten einmal in der Elternklasse schreiben und jede Kindklasse sofort davon profitiert.

challenge icon

Aufgabe

Einfach

Lass uns eine einfache Kreaturenhierarchie aufbauen, um die Methodenvererbung in Aktion zu sehen! Du wirst eine Elternklasse Animal und eine Kindklasse Dog erstellen und dann demonstrieren, dass Dog-Instanzen Methoden verwenden können, die nur in Animal definiert sind.

Du wirst deinen Code über drei Dateien organisieren:

  • Animal.lua: Definiere deine Elternklasse mit dem Standard-Klassenmuster. Füge einen :new(name)-Konstruktor hinzu, der den Namen des Tieres speichert, und eine :speak()-Methode, die den Namen des Tieres gefolgt von makes a sound ausgibt. Gib die Klasse am Ende der Datei zurück.
  • Dog.lua: Definiere deine Kindklasse, die von Animal erbt. Binde das Animal-Modul mit require ein und richte die Vererbungskette ein, damit Dog auf die Methoden von Animal zugreifen kann. Füge einen :new(name)-Konstruktor hinzu, der den Namen speichert und Dog als Metatabelle setzt. Die Dog-Klasse sollte KEINE eigene :speak()-Methode definieren – sie wird diese von Animal erben.
  • main.lua: Binde dein Dog-Modul mit require ein, lies einen Namen aus der Eingabe, erstelle eine Dog-Instanz mit diesem Namen und rufe die :speak()-Methode darauf auf.

Du erhältst eine Eingabe: den Namen des Hundes.

Wenn die Eingabe zum Beispiel Buddy ist, sollte die Ausgabe wie folgt aussehen:

Buddy makes a sound

Der Zauber hierbei ist, dass deine Dog-Klasse niemals :speak() definiert, der Aufruf auf einer Dog-Instanz aber dennoch perfekt funktioniert. Lua folgt der Suchkette von der Dog-Instanz zur Dog-Klasse und dann zur Animal-Klasse, wo sie die Methode findet. Das ist Vererbung in der Praxis!

Spickzettel

Instanzen von Kindklassen erhalten automatisch Zugriff auf alle Methoden der Elternklasse über die Lookup-Kette von Lua. Wenn eine Methode für eine Instanz aufgerufen wird, durchsucht Lua jede verbundene Tabelle, bis die Methode gefunden wird.

Vererbung einrichten

Definition der Elternklasse:

local Animal = {}
Animal.__index = Animal

function Animal:new()
    local obj = {}
    setmetatable(obj, Animal)
    return obj
end

function Animal:breathe()
    print("Breathing...")
end

Kindklasse mit Vererbungsverknüpfung:

local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new()
    local obj = {}
    setmetatable(obj, Dog)
    return obj
end

Vererbte Methoden verwenden

Kind-Instanzen können Methoden der Elternklasse aufrufen, selbst wenn diese nicht in der Kindklasse definiert sind:

local buddy = Dog:new()
buddy:breathe()  -- Ausgabe: Breathing...

Die Lookup-Kette: Lua prüft buddyDogAnimal, bis die Methode gefunden wird.

Klassenorganisation in mehreren Dateien

Datei der Elternklasse (Animal.lua):

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

return Animal

Datei der Kindklasse (Dog.lua):

local Animal = require("Animal")

local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new(name)
    local obj = {name = name}
    setmetatable(obj, Dog)
    return obj
end

return Dog

Verwendung in der Hauptdatei:

local Dog = require("Dog")
local buddy = Dog:new("Buddy")
buddy:speak()  -- Ausgabe: Buddy makes a sound

Probier es selbst

-- main.lua: Einstiegspunkt

local Dog = require('Dog')

-- Lies den Namen des Hundes aus der Eingabe
local name = io.read()

-- TODO: Erstelle eine Dog-Instanz mit dem angegebenen Namen

-- TODO: Rufe die :speak()-Methode für die Dog-Instanz auf
quiz iconTeste dich selbst

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