0Pricing
Lua Academy · Lekcja

Pojedyncze dziedziczenie z łańcuchowaniem __index

Proszę ustawić klasę nadrzędną jako __index metatabeli, aby dziedziczyć metody.

Pojedyncze dziedziczenie z łańcuchowaniem __index to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Lua Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Lua Academy zawiera 4 lekcji w sumie.

Łańcuch prototypów

Dziedziczenie pojedyncze działa przez ustawienie __index klasy potomnej na klasę nadrzędną. Gdy metoda nie zostanie znaleziona w klasie potomnej, Lua szuka jej w klasie nadrzędnej. W ten sposób powstaje łańcuch prototypów.

local Base={}
Base.__index=Base
function Base.new() return setmetatable({},Base) end
function Base:greet() print("Hello from Base") end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})  -- Child inherits Base

function Child.new() return setmetatable({},Child) end

local c=Child.new()
c:greet()  -- Hello from Base (inherited)

Kolejność rozwiązywania metod

Podczas wywoływania metody na instancji: (1) wyszukiwanie w tabeli instancji, (2) wyszukiwanie w Child (przez __index), (3) wyszukiwanie w Base (przez __index metatabeli Child). Wygrywa pierwsze znalezione dopasowanie.

local Base={}
Base.__index=Base
function Base:who() print("I am Base") end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
function Child:who() print("I am Child") end  -- override

local b=setmetatable({},Base)
local c=setmetatable({},Child)
b:who()  -- I am Base
c:who()  -- I am Child (overrides)

Dziedziczenie konstruktorów

Klasy potomne mogą ponownie używać konstruktorów klas nadrzędnych, wywołując je, albo definiować własne konstruktory rozszerzające inicjalizację klasy nadrzędnej.

local Animal={}
Animal.__index=Animal
function Animal.new(name,sound)
  return setmetatable({name=name,sound=sound},Animal)
end
function Animal:speak() print(self.name..": "..self.sound) end

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

function Dog.new(name)
  local self = Animal.new(name,"Woof")
  return setmetatable(self,Dog)
end
function Dog:fetch(item) print(self.name.." fetches "..item) end

local d=Dog.new("Rex")
d:speak(); d:fetch("ball")

Sprawdzanie pochodzenia

Należy przejść w górę łańcucha metatabel, aby sprawdzić, czy klasa obiektu dziedziczy po określonej bazie. Tak działa instanceof w Lua.

local function instanceof(obj, cls)
  local mt = getmetatable(obj)
  while mt do
    if mt == cls then return true end
    mt = getmetatable(mt)
  end
  return false
end

Wywołanie super

Wersję przesłoniętej metody klasy nadrzędnej należy wywołać, uzyskując do niej bezpośredni dostęp przez tabelę klasy nadrzędnej.

local Base={}
Base.__index=Base
function Base:init(x) self.x=x end
function Base:value() return self.x end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
function Child:init(x,y)
  Base.init(self,x)  -- call parent
  self.y=y
end
function Child:value() return Base.value(self)+self.y end

local c=setmetatable({},Child)
c:init(3,4)
print(c:value())  -- 7

Głęboki łańcuch

Należy zbudować trzypoziomową hierarchię: A → B → C. Wyszukiwanie metody przechodzi przez cały łańcuch, aż znajdzie metodę.

local A={}
A.__index=A
function A:aMethod() print("A method") end

local B={}
B.__index=B
setmetatable(B,{__index=A})
function B:bMethod() print("B method") end

local C={}
C.__index=C
setmetatable(C,{__index=B})

local c=setmetatable({},C)
c:bMethod()  -- from B
c:aMethod()  -- from A

Przesłanianie pól

Instancja może przesłonić pola na poziomie klasy, ustawiając je bezpośrednio. Pole klasy nie zostaje zmienione — jest tylko przesłaniane dla tej instancji.

local Creature={}
Creature.__index=Creature
Creature.hp=100
Creature.speed=10

function Creature.new()
  return setmetatable({},Creature)
end

local fast=Creature.new()
fast.speed=20  -- override for this instance

local normal=Creature.new()

print(fast.speed,normal.speed,Creature.speed)  -- 20  10  10

Dziedziczenie na poziomie klas

Ustawienie setmetatable(Child, {__index=Parent}) powoduje, że wyszukiwanie na poziomie klasy przechodzi do klasy nadrzędnej. Oznacza to, że Child.classMethod() znajdzie metody w klasie nadrzędnej, jeśli nie zostały przesłonięte.

local Vehicle={}
Vehicle.__index=Vehicle
Vehicle.maxSpeed=120
function Vehicle.describe() print("Vehicle") end

local Car={}
Car.__index=Car
setmetatable(Car,{__index=Vehicle})

Car.describe()  -- Vehicle (inherited class method)
print(Car.maxSpeed)  -- 120 (inherited class field)

Łańcuch inicjalizacji

Aby zapewnić prawidłową inicjalizację, konstruktory klas potomnych wywołują konstruktory klas nadrzędnych, dzięki czemu stan klasy nadrzędnej zostaje przygotowany. Należy przeprowadzić inicjalizację w całej hierarchii.

local Base={}
Base.__index=Base
function Base:_init(name) self.name=name end

local Mid={}
Mid.__index=Mid
setmetatable(Mid,{__index=Base})
function Mid:_init(name,level)
  Base._init(self,name)
  self.level=level
end

local Top={}
Top.__index=Top
setmetatable(Top,{__index=Mid})
function Top.new(name,level,role)
  local self=setmetatable({},Top)
  Mid._init(self,name,level)
  self.role=role
  return self
end

local t=Top.new("Alice",5,"admin")
print(t.name,t.level,t.role)

Abstrakcyjne klasy bazowe

Należy utworzyć klasę bazową z niezaimplementowanymi metodami, które zgłaszają błędy. Klasy potomne muszą przesłonić te metody. Wymusza to kontrakty interfejsów w dynamicznym systemie typów Lua.

local Serializer={}
Serializer.__index=Serializer
function Serializer:encode(data)
  error(self._type.." must implement encode()",2)
end
function Serializer:decode(str)
  error(self._type.." must implement decode()",2)
end

local JSONSerializer={_type="JSON"}
setmetatable(JSONSerializer,{__index=Serializer})
function JSONSerializer:encode(data)
  return "{"..tostring(data.key).."}"
end

local j=setmetatable({_type="JSON"},JSONSerializer)
print(j:encode({key="val"}))

Pytanie o dziedziczenie

Co umożliwia dziedziczenie pojedyncze w Lua?

Podsumowanie: dziedziczenie pojedyncze

Ustawienie setmetatable(Child, {__index = Parent}) umożliwia dziedziczenie metod. Łańcuch __index zapewnia automatyczne delegowanie. Przesłanianie uzyskuje się przez zdefiniowanie metod w Child, a klasę nadrzędną należy wywoływać jawnie za pomocą Parent.method(self).

Często zadawane pytania

Czy lekcja „Pojedyncze dziedziczenie z łańcuchowaniem __index” jest bezpłatna?

Tak — pełny tekst „Pojedyncze dziedziczenie z łańcuchowaniem __index” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Lua Academy, przejdź na CoddyKit PRO. Kurs Lua Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Pojedyncze dziedziczenie z łańcuchowaniem __index”?

Proszę ustawić klasę nadrzędną jako __index metatabeli, aby dziedziczyć metody. Ćwiczysz Lua Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Lua Academy?

Nie wymagamy żadnego doświadczenia. Lua Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Pojedyncze dziedziczenie z łańcuchowaniem __index”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Lua Academy?

Tak. Każda lekcja Lua Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Pojedyncze dziedziczenie z łańcuchowaniem __index
  2. Wywoływanie metod klasy bazowej za pomocą super
  3. Wzorce mixinów
  4. Przesłanianie i polimorfizm
← Powrót do Lua Academy