0Pricing
Lua Academy · Lezione

Chiamata dei metodi del padre con super

Chiami esplicitamente i metodi della classe base per un'inizializzazione cooperativa.

Chiamata dei metodi del padre con super è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.

Perché utilizzare le chiamate super?

Quando una classe figlia sovrascrive un metodo del genitore ma deve comunque utilizzarne la logica, chiama esplicitamente il metodo del genitore. Lua non dispone della parola chiave super: si fa riferimento direttamente alla tabella del genitore: 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 nel costruttore

I costruttori delle classi figlie chiamano quelli dei genitori tramite Parent.new() o Parent._init(self,...). Questo garantisce che l'inizializzazione del genitore venga eseguita per ogni istanza figlia.

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)

Inizializzazione cooperativa

Nelle gerarchie profonde, ogni livello inizializza solo i propri campi e chiama l'inizializzazione del genitore. In questo modo ogni classe è responsabile esclusivamente dei propri campi.

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

Crei un helper super(self) che restituisca un oggetto proxy in grado di chiamare i metodi del genitore con self. In questo modo si ottiene una sintassi più ordinata rispetto a 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")

Più livelli

Quando sono presenti più livelli di ereditarietà, ogni livello chiama il genitore diretto. La catena si propaga automaticamente.

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

Estensione dei metodi

Estenda un metodo del genitore: chiami la versione del genitore, quindi aggiunga il comportamento supplementare. Si tratta di advice "prima" o "dopo" senza un framework AOP formale.

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

Evitare i problemi delle chiamate super

Utilizzi sempre il nome esatto della classe genitore, non getmetatable(self).__index, per le chiamate super: la ricerca nella metatabella può restituire una classe intermedia anziché il vero genitore. Sia esplicito per maggiore chiarezza e correttezza.

-- 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 per __tostring

Sovrascriva __tostring in una classe figlia includendo anche la rappresentazione del genitore, per ottenere una descrizione completa.

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)

Template Method protetto

Il pattern Template Method: la classe base definisce lo scheletro di un algoritmo con chiamate a passaggi astratti; le sottoclassi implementano tali passaggi.

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

Convenzione per le chiamate super

Convenzione: anteponga _ alle funzioni di inizializzazione esclusivamente interne (ad esempio _init) ed esponga un new() pubblico solo nel costruttore di livello superiore. Questo mantiene ordinata la catena di ereditarietà.

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

Domanda sulle chiamate super

Come si chiama un metodo del genitore in Lua?

Riepilogo: chiamate super

Chiami sempre i metodi del genitore tramite un riferimento esplicito alla classe: Parent.method(self, ...). Utilizzi la convenzione _init per i costruttori cooperativi attraverso i diversi livelli di ereditarietà.

Domande Frequenti

La lezione «Chiamata dei metodi del padre con super» è gratuita?

Sì — il testo completo di «Chiamata dei metodi del padre con super» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.

Cosa imparerò in «Chiamata dei metodi del padre con super»?

Chiami esplicitamente i metodi della classe base per un'inizializzazione cooperativa. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Lua Academy?

Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Chiamata dei metodi del padre con super»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Lua Academy?

Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Ereditarietà singola con concatenamento di __index
  2. Chiamata dei metodi del padre con super
  3. Pattern mixin
  4. Override e polimorfismo
← Torna a Lua Academy