Wywoływanie metod klasy bazowej za pomocą super
Proszę jawnie wywoływać metody klasy bazowej w celu zapewnienia współpracującej inicjalizacji.
Wywoływanie metod klasy bazowej za pomocą super to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 2 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.
Dlaczego wywołania super?
Gdy klasa potomna przesłania metodę klasy nadrzędnej, ale nadal potrzebuje jej logiki, wywołuje metodę klasy nadrzędnej jawnie. Lua nie ma słowa kluczowego super — należy bezpośrednio odwołać się do tabeli klasy nadrzędnej: Parent.method(self, args).
local Base={}
Base.__index=Base
function Base:describe()
return "Base[name="..self.name.."]"
end
local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
function Child:describe()
local parentDesc = Base.describe(self) -- super call
return parentDesc .. " + Child[extra=true]"
end
local c=setmetatable({name="X"},Child)
print(c:describe())super w konstruktorze
Konstruktory klas potomnych wywołują konstruktory klas nadrzędnych za pomocą Parent.new() lub Parent._init(self,...). Dzięki temu inicjalizacja klasy nadrzędnej jest wykonywana dla każdej instancji klasy potomnej.
local Animal={}
Animal.__index=Animal
function Animal._init(self,name,sound)
self.name=name; self.sound=sound; self.alive=true
end
local Dog={}
Dog.__index=Dog; setmetatable(Dog,{__index=Animal})
function Dog.new(name,breed)
local self=setmetatable({},Dog)
Animal._init(self,name,"Woof") -- super init
self.breed=breed
return self
end
local d=Dog.new("Rex","Lab")
print(d.name,d.sound,d.breed)Kooperatywna inicjalizacja
W głębokich hierarchiach każdy poziom inicjalizuje tylko własne pola i wywołuje metodę init klasy nadrzędnej. Dzięki temu każda klasa odpowiada wyłącznie za własne pola.
local A={}
function A._init(self,x) self.x=x end
local B={}
function B._init(self,x,y) A._init(self,x); self.y=y end
local C={}
C.__index=C
function C.new(x,y,z)
local self=setmetatable({},C)
B._init(self,x,y)
self.z=z
return self
end
local c=C.new(1,2,3)
print(c.x,c.y,c.z) -- 1 2 3Wrapper super
Należy utworzyć pomocniczą funkcję super(self), która zwraca obiekt proxy wywołujący metody klasy nadrzędnej z self. Zapewnia to czytelniejszą składnię niż Parent.method(self, ...).
local function super(self)
local mt = getmetatable(getmetatable(self).__index)
if mt then
return setmetatable({}, {__index=function(_,k)
local parentCls = mt.__index or mt
return function(...) return parentCls[k](self,...) end
end})
end
end
print("super() helper pattern shown")Wiele poziomów
Gdy istnieje wiele poziomów dziedziczenia, każdy poziom wywołuje bezpośrednią klasę nadrzędną. Łańcuch propaguje się automatycznie.
local L1={} L1.__index=L1
function L1:intro() return "L1" end
local L2={} L2.__index=L2
setmetatable(L2,{__index=L1})
function L2:intro() return L1.intro(self).."+L2" end
local L3={} L3.__index=L3
setmetatable(L3,{__index=L2})
function L3:intro() return L2.intro(self).."+L3" end
local obj=setmetatable({},L3)
print(obj:intro()) -- L1+L2+L3Rozszerzanie metod
Aby rozszerzyć metodę klasy nadrzędnej, należy wywołać jej wersję, a następnie dodać dodatkowe działanie. Jest to porada typu „przed” lub „po” bez formalnego frameworka AOP.
local Logger={} Logger.__index=Logger
function Logger:log(msg) print("[LOG] "..msg) end
local TimedLogger={} TimedLogger.__index=TimedLogger
setmetatable(TimedLogger,{__index=Logger})
function TimedLogger:log(msg)
local ts=os.date("%H:%M:%S")
Logger.log(self,"["..ts.."] "..msg) -- augment
end
local tl=setmetatable({},TimedLogger)
tl:log("Server started")Unikanie pułapek super
W wywołaniach super należy zawsze używać dokładnej nazwy klasy nadrzędnej, a nie getmetatable(self).__index — wyszukiwanie przez metatabelę może zwrócić klasę pośrednią, a nie rzeczywistą klasę nadrzędną. Jawne wskazanie klasy zapewnia czytelność i poprawność.
-- Correct: explicit parent reference
function Child:init(x)
Base.init(self, x) -- explicit, clear
end
-- Fragile: uses metatable lookup
function Child:initBad(x)
local parent = getmetatable(getmetatable(self).__index)
-- This may not be Base if hierarchy changes!
end
print("Be explicit with parent class references")super dla __tostring
Należy przesłonić __tostring w klasie potomnej, uwzględniając jednocześnie reprezentację klasy nadrzędnej, aby uzyskać pełny opis.
local Base={}
Base.__index=Base
Base.__tostring=function(self) return "Base("..self.name..")" end
local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
Child.__tostring=function(self)
local baseStr = Base.__tostring(self)
return baseStr.." + Child(level="..self.level..")"
end
local c=setmetatable({name="X",level=5},Child)
print(tostring(c)) -- Base(X) + Child(level=5)Chroniona metoda szablonowa
Wzorzec metody szablonowej: klasa bazowa definiuje szkielet algorytmu z wywołaniami abstrakcyjnych kroków, a klasy potomne implementują te kroki.
local Processor={} Processor.__index=Processor
function Processor:run(data)
data = self:preProcess(data)
data = self:process(data)
return self:postProcess(data)
end
function Processor:preProcess(d) return d end
function Processor:postProcess(d) return d end
function Processor:process(d) error("implement process()") end
local Upper={} Upper.__index=Upper
setmetatable(Upper,{__index=Processor})
function Upper:process(d) return d:upper() end
local p=setmetatable({},Upper)
print(p:run("hello")) -- HELLOKonwencja wywołań super
Konwencja: wewnętrzne funkcje inicjalizujące należy poprzedzać znakiem _ (np. _init), a publiczne new() udostępniać tylko na najwyższym poziomie konstruktora. Utrzymuje to przejrzystość łańcucha dziedziczenia.
-- Convention summary:
-- Animal._init(self, ...) -- used for super calls
-- Dog.new(...) -- only public constructor
-- Never call Dog._init from outside
local Foo={} Foo.__index=Foo
function Foo._init(self,x) self.x=x end
function Foo.new(x)
return setmetatable({},Foo):_init(x) or
(function() local s=setmetatable({},Foo); Foo._init(s,x); return s end)()
end
print("Convention: _init for super, new() for public")Pytanie o wywołanie super
Jak wywołać metodę klasy nadrzędnej w Lua?
Podsumowanie: wywołania super
Metody klas nadrzędnych należy zawsze wywoływać przez jawne odwołanie do klasy: Parent.method(self, ...). Należy stosować konwencję _init dla kooperatywnych konstruktorów na kolejnych poziomach dziedziczenia.
Często zadawane pytania
Czy lekcja „Wywoływanie metod klasy bazowej za pomocą super” jest bezpłatna?
Tak — pełny tekst „Wywoływanie metod klasy bazowej za pomocą super” 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 „Wywoływanie metod klasy bazowej za pomocą super”?
Proszę jawnie wywoływać metody klasy bazowej w celu zapewnienia współpracującej inicjalizacji. Ć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 2 z 4.
Ile czasu zajmuje lekcja „Wywoływanie metod klasy bazowej za pomocą super”?
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
- Pojedyncze dziedziczenie z łańcuchowaniem __index
- Wywoływanie metod klasy bazowej za pomocą super
- Wzorce mixinów
- Przesłanianie i polimorfizm