0Pricing
Lua Academy · Aula

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
end

Chamada 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())  -- 7

Cadeia 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 A

Sobrescrevendo 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  10

Heranç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

  1. Herança única com encadeamento de __index
  2. Chamando métodos da classe-pai com super
  3. Padrões de mixins
  4. Sobrescrita e polimorfismo
← Voltar para Lua Academy