Menu
Coddy logo textTech

Konfiguracja dziedziczenia

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

Do tej pory tworzyłeś klasy, w których każdy obiekt wyszukuje metody w pojedynczej tablicy prototypów. Ale co, jeśli chcesz, aby jedna klasa bazowała na innej? Właśnie tu przydaje się dziedziczenie: klasa potomna może uzyskać dostęp do wszystkiego, co zawiera klasa nadrzędna, i jednocześnie dodawać własne funkcje.

Kluczowy wniosek jest taki, że sama tabela klasy może mieć metatabelę. Gdy Lua nie może czegoś znaleźć w klasie potomnej, szuka w __index metatabeli klasy potomnej, który wskazuje na klasę nadrzędną.

-- Klasa bazowa
local Animal = {}
Animal.__index = Animal

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

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

A teraz konfiguracja dziedziczenia. Tworzymy klasę potomną i ustawiamy jej metatabelę tak, aby odwoływała się do klasy nadrzędnej:

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

Ta pojedyncza linia, setmetatable(Dog, {__index = Animal}), tworzy powiązanie dziedziczenia. Gdy instancja Dog wywołuje metodę, której nie znaleziono w Dog, Lua sprawdza Animal.

Łańcuch wyszukiwania działa tak: instancja → Dog → Animal. Każdy krok używa __index, aby znaleźć następną tabelę do przeszukania. Dzięki temu klasy potomne automatycznie dziedziczą wszystkie metody klas nadrzędnych bez ich kopiowania.

challenge icon

Wyzwanie

Łatwy

Zbudujmy Twoją pierwszą hierarchię dziedziczenia! Utworzysz prostą relację między klasą nadrzędną i podrzędną, w której klasa Machine będzie klasą bazową, a klasa Robot będzie po niej dziedziczyć.

Rozmieścisz kod w trzech plikach:

  • Machine.lua: Zdefiniuj klasę nadrzędną, używając standardowego wzorca klas. Dodaj konstruktor :new() i metodę :status(), która wyświetla Machine is operational. Nie zapomnij skonfigurować __index i zwrócić klasy na końcu pliku.
  • Robot.lua: Zdefiniuj klasę podrzędną, która dziedziczy po Machine. Załaduj moduł Machine, skonfiguruj tabelę Robot z własnym __index i ustanów relację dziedziczenia za pomocą setmetatable(Robot, {__index = Machine}). Dodaj konstruktor :new(), który tworzy instancję z Robot jako jej metatabelą.
  • main.lua: Połącz wszystko, ładując moduł Robot, tworząc instancję Robot i wywołując odziedziczoną metodę :status().

Kluczowa koncepcja polega na tym, że klasa Robot nie definiuje samodzielnie metody :status(). Dziedziczy tę metodę po Machine za pośrednictwem łańcucha metatabel. Gdy wywołasz :status() na instancji Robot, Lua najpierw sprawdzi klasę Robot, nie znajdzie tam metody, a następnie podąży za odnośnikiem __index do Machine, gdzie ją znajdzie.

Oczekiwany wynik:

Machine is operational

Ta pojedyncza linia dowodzi, że dziedziczenie działa. Robot pomyślnie uzyskał dostęp do metody zdefiniowanej wyłącznie w swojej klasie nadrzędnej!

Spróbuj swoich sił

-- main.lua: Połącz wszystko w całość

-- TODO: Załaduj moduł Robot za pomocą require

-- TODO: Utwórz instancję Robot za pomocą Robot:new()

-- TODO: Wywołaj odziedziczoną metodę :status() na swojej instancji robota
-- To powinno wyświetlić "Machine is operational"
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