Menu
Coddy logo textTech

Verknüpfung mit __index

Teil des Abschnitts Objektorientierte Programmierung der Lua-Journey von Coddy. Lektion 7 von 70.

Sie haben eine Prototyp-Tabelle mit Eigenschaften und Methoden, aber wie bringen Sie ein neues Objekt dazu, diese tatsächlich zu verwenden? Die Antwort liegt in der Metamethode __index.

Wenn Sie auf einen Schlüssel zugreifen, der in einer Tabelle nicht existiert, gibt Lua normalerweise nil zurück. Wenn die Tabelle jedoch eine Metatabelle mit einem __index-Feld hat, sucht Lua stattdessen dort. Indem Sie __index so einstellen, dass es auf Ihren Prototyp zeigt, werden alle fehlenden Schlüssel automatisch im Prototyp gefunden:

local Dog = {
    species = "Canis familiaris",
    legs = 4
}

function Dog:bark()
    print("Woof!")
end

-- Erstelle eine leere Instanz
local myDog = {}

-- Verknüpfe sie mit dem Prototyp
setmetatable(myDog, { __index = Dog })

print(myDog.species)  -- Ausgabe: Canis familiaris
myDog:bark()          -- Ausgabe: Woof!

Die Tabelle myDog ist komplett leer, dennoch funktioniert der Zugriff auf myDog.species. Wenn Lua species in myDog nicht findet, prüft es das __index der Metatabelle und findet es in Dog.

Dies ist die Grundlage der objektorientierten Programmierung in Lua. Die Instanz kann ihre eigenen eindeutigen Daten haben, während gemeinsames Verhalten im Prototyp lebt. In der nächsten Lektion lernst du, wie du dieses Muster in eine saubere Konstruktorfunktion verpackst.

challenge icon

Aufgabe

Einfach

Setzen wir nun die Metamethode __index in die Praxis um! Du erstellst einen Prototyp und verknüpfst eine Instanz mit ihm, sodass die Instanz auf Eigenschaften und Methoden zugreifen kann, die sie nicht direkt besitzt.

Du wirst deinen Code auf zwei Dateien aufteilen:

  • Robot.lua: Definiere eine Prototyp-Tabelle Robot mit:
    • einem model-Feld, das auf "RX-100" gesetzt ist
    • einem batteryLevel-Feld, das auf 100 gesetzt ist
    • einer :status()-Methode, die den aktuellen Zustand des Roboters ausgibt
    Gib die Tabelle am Ende der Datei zurück.
  • main.lua: Binde das Robot-Modul ein, erstelle anschließend eine leere Instanz-Tabelle und verknüpfe sie mithilfe von setmetatable mit __index mit dem Robot-Prototyp. Dadurch kann deine leere Instanz auf alles aus dem Prototyp zugreifen.

Du erhältst eine Eingabe: einen Namen, der deiner Roboterinstanz zugewiesen werden soll.

Nachdem du die Instanz mit dem Prototyp verknüpft hast:

  1. Weise den eingegebenen Namen dem name-Feld deiner Instanz zu (dadurch wird er für die Instanz eindeutig)
  2. Rufe die :status()-Methode für deine Instanz auf

Deine :status()-Methode sollte exakt in diesem Format ausgeben:

[name] ([model]) - Battery: [batteryLevel]%

Wenn die Eingabe beispielsweise Sparky lautet, sollte die Ausgabe folgendermaßen aussehen:

Sparky (RX-100) - Battery: 100%

Beachte, dass die Instanz ihren eigenen name besitzt, aber über die model-Verknüpfung auf batteryLevel und __index aus dem Prototyp zugreift.

Probier es selbst

-- Eingabe lesen
local name = io.read()

-- Das Robot-Modul anfordern
local Robot = require('Robot')

-- TODO: Eine leere Instanz-Tabelle erstellen

-- TODO: Die Instanz mit dem Robot-Prototyp verknüpfen, indem setmetatable mit __index verwendet wird

-- TODO: Den eingegebenen Namen dem Namensfeld deiner Instanz zuweisen

-- TODO: Die Methode :status() auf deiner Instanz aufrufen
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 Objektorientierte Programmierung

Übe selbstständig: Online-Lua-Compiler