Herança única com encadeamento de __index
Defina uma classe-pai como __index da metatabela para herdar métodos.
Herança única com encadeamento de __index é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 1 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.
Cadeia de Protótipos
A herança simples funciona definindo o __index de uma classe filha como a classe pai. Quando um método não é encontrado na filha, Lua o procura na classe pai. Isso cria uma cadeia de protótipos.
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)Ordem de Resolução de Métodos
Ao chamar um método em uma instância: (1) procure na tabela da instância, (2) procure em Child (por meio de __index), (3) procure em Base (por meio do __index da metatabela de Child). A primeira correspondência vence.
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)Herdando Construtores
As classes filhas podem reutilizar os construtores dos pais chamando-os ou definir os próprios construtores para estender a inicialização da classe pai.
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")Verificando a Ancestralidade
Percorra a cadeia de metatabelas para verificar se a classe de um objeto herda de uma determinada base. É assim que instanceof funciona em 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
endChamada ao Pai
Chame a versão do método da classe pai que foi sobrescrito acessando-o diretamente pela tabela da classe pai.
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()) -- 7Cadeia Profunda
Crie uma hierarquia de três níveis: A → B → C. A busca de métodos percorre toda a cadeia até encontrar o método.
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 ASobrescrevendo Campos
Uma instância pode sobrescrever campos no nível da classe definindo-os diretamente. O campo da classe não é alterado — ele apenas fica oculto para essa instância.
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 10Herança no Nível da Classe
Definir setmetatable(Child, {__index=Parent}) faz com que as buscas no nível da classe continuem na classe pai. Isso significa que Child.classMethod() encontra métodos na classe pai se eles não tiverem sido sobrescritos.
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)Cadeia de Inicialização
Para uma inicialização correta, os construtores filhos chamam os construtores pais para garantir que o estado do pai seja configurado. Encadeie a inicialização na hierarquia.
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)Classes Base Abstratas
Crie uma classe base com métodos não implementados que gerem erros. As subclasses devem sobrescrever esses métodos. Isso impõe contratos de interface no sistema de tipos dinâmico de 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"}))Pergunta sobre Herança
O que possibilita a herança simples em Lua?
Revisão: Herança Simples
Defina setmetatable(Child, {__index = Parent}) para herdar métodos. A cadeia de __index fornece delegação automática. Para sobrescrever, defina métodos em Child; para chamar o pai explicitamente, use Parent.method(self).
Perguntas Frequentes
A aula “Herança única com encadeamento de __index” é grátis?
Sim — o texto completo de “Herança única com encadeamento de __index” é 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 “Herança única com encadeamento de __index”?
Defina uma classe-pai como __index da metatabela para herdar métodos. 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 1 de 4.
Quanto tempo leva a aula “Herança única com encadeamento de __index”?
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