0Pricing
Lua Academy · Lekcja

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 3

Wrapper 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+L3

Rozszerzanie 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"))  -- HELLO

Konwencja 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

  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