Menu
Coddy logo textTech

Łączenie za pomocą __index

Część sekcji Programowanie obiektowe ścieżki Lua w Coddy. Lekcja 7 z 70.

Masz tabelę prototypu z właściwościami i metodami, ale jak sprawić, by nowy obiekt faktycznie z niej korzystał? Odpowiedzią jest metametoda __index.

Gdy odwołujesz się do klucza, który nie istnieje w tabeli, Lua zwykle zwraca nil. Jeśli jednak tabela ma metatabelę z polem __index, Lua sprawdzi zamiast tego to pole. Ustawiając __index tak, aby wskazywało na prototyp, brakujące klucze są automatycznie wyszukiwane w prototypie:

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

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

-- Utwórz pustą instancję
local myDog = {}

-- Połącz ją z prototypem
setmetatable(myDog, { __index = Dog })

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

Tablica myDog jest całkowicie pusta, a mimo to dostęp do myDog.species działa. Gdy Lua nie znajduje species w myDog, sprawdza __index w metatabeli i znajduje tę wartość w Dog.

To podstawa programowania obiektowego w Lua. Instancja może mieć własne, unikalne dane, a współdzielone zachowanie znajduje się w prototypie. W następnej lekcji dowiesz się, jak ująć ten wzorzec w przejrzystą funkcję konstruktora.

challenge icon

Wyzwanie

Łatwy

Teraz zastosujmy w praktyce metametodę __index! Utworzysz prototyp i połączysz z nim instancję, dzięki czemu instancja będzie mogła uzyskiwać dostęp do właściwości i metod, których nie ma bezpośrednio.

Rozmieścisz kod w dwóch plikach:

  • Robot.lua: Zdefiniuj tabelę prototypu Robot z:
    • Polem model ustawionym na "RX-100"
    • Polem batteryLevel ustawionym na 100
    • Metodą :status(), która wypisuje bieżący stan robota
    Zwróć tabelę na końcu pliku.
  • main.lua: Załaduj moduł Robot, a następnie utwórz pustą tabelę instancji i połącz ją z prototypem Robot za pomocą setmetatable z __index. Dzięki temu pusta instancja będzie mogła uzyskiwać dostęp do wszystkiego z prototypu.

Otrzymasz jedno wejście: nazwę, którą przypiszesz instancji robota.

Po połączeniu instancji z prototypem:

  1. Przypisz nazwę z wejścia do pola name instancji (dzięki temu będzie ono unikalne dla tej instancji)
  2. Wywołaj metodę :status() na swojej instancji

Metoda :status() powinna wypisywać tekst w dokładnie takim formacie:

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

Na przykład, jeśli wejściem jest Sparky, wynikiem powinno być:

Sparky (RX-100) - Battery: 100%

Zauważ, że instancja ma własne pole name, ale uzyskuje dostęp do model i batteryLevel z prototypu za pośrednictwem połączenia __index.

Spróbuj swoich sił

-- Wczytaj dane wejściowe
local name = io.read()

-- Załaduj moduł Robot
local Robot = require('Robot')

-- TODO: Utwórz pustą tabelę instancji

-- TODO: Powiąż instancję z prototypem Robot za pomocą setmetatable i __index

-- TODO: Przypisz wczytaną nazwę do pola name swojej instancji

-- TODO: Wywołaj metodę :status() na swojej instancji
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Lua online