Chamando métodos da classe-pai com super
Chame explicitamente métodos da classe-base para uma inicialização cooperativa.
Chamando métodos da classe-pai com super é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Lua Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Lua Academy inclui 4 aulas no total.
Por que Fazer Chamadas ao Pai?
Quando uma filha sobrescreve um método do pai, mas ainda precisa da lógica do pai, ela chama explicitamente o método da classe pai. Lua não tem a palavra-chave super — você faz referência diretamente à tabela do pai: 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 no Construtor
Os construtores filhos chamam os construtores pais por meio de Parent.new() ou Parent._init(self,...). Isso garante que a inicialização do pai seja executada para cada instância filha.
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)Inicialização Cooperativa
Em hierarquias profundas, cada nível inicializa apenas seus próprios campos e chama a inicialização do pai. Isso mantém cada classe responsável somente por seus próprios campos.
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 3Invólucro de super
Crie um auxiliar super(self) que retorne um objeto proxy capaz de chamar métodos do pai com self. Isso oferece uma sintaxe mais limpa do que 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")Vários Níveis
Quando há vários níveis de herança, cada nível chama seu pai imediato. A cadeia se 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+L3Ampliação de Métodos
Amplie um método do pai: chame a versão do pai e depois adicione um comportamento extra. Isso é um aconselhamento "antes" ou "depois" sem uma estrutura formal de 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")Evitando Armadilhas das Chamadas ao Pai
Sempre use o nome exato da classe pai, e não getmetatable(self).__index, nas chamadas ao pai — a busca na metatabela pode retornar uma classe intermediária, não o verdadeiro pai. Seja explícito para garantir clareza e correção.
-- 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 para __tostring
Sobrescreva __tostring em uma filha incluindo a representação do pai para obter uma descrição 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)Método de Modelo Protegido
O padrão de método de modelo: a classe base define o esqueleto de um algoritmo com chamadas a etapas abstratas; as subclasses implementam essas etapas.
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")) -- HELLOConvenção para Chamadas ao Pai
Convenção: prefixe funções de inicialização somente internas com _ (por exemplo, _init) e exponha um new() público apenas no construtor de nível superior. Isso mantém a cadeia de herança organizada.
-- 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")Pergunta sobre Chamada ao Pai
Como você chama um método da classe pai em Lua?
Revisão: Chamadas ao Pai
Sempre chame os métodos da classe pai usando uma referência explícita à classe: Parent.method(self, ...). Use a convenção _init para construtores cooperativos entre os níveis de herança.
Perguntas Frequentes
A aula “Chamando métodos da classe-pai com super” é grátis?
Sim — o texto completo de “Chamando métodos da classe-pai com super” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Lua Academy, atualize para CoddyKit PRO. O curso de Lua Academy inclui 4 aulas no total.
O que vou aprender em “Chamando métodos da classe-pai com super”?
Chame explicitamente métodos da classe-base para uma inicialização cooperativa. Você pratica Lua Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Lua Academy?
Nenhuma experiência prévia é necessária. Lua Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Chamando métodos da classe-pai com super”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Lua Academy?
Sim. Cada aula de Lua Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Herança única com encadeamento de __index
- Chamando métodos da classe-pai com super
- Padrões de mixins
- Sobrescrita e polimorfismo