Herdando Métodos
Parte da seção Object Oriented Programming do Journey de Lua da Coddy — lição 32 de 70.
Com o link de herança estabelecido, as instâncias da classe filha ganham acesso automaticamente a todos os métodos da classe pai. Isso acontece através da cadeia de busca (lookup chain) do Lua — quando você chama um método em uma instância, o Lua pesquisa em cada tabela conectada até encontrar o que você está procurando.
Considere esta configuração onde Animal define um método :breathe():
local Animal = {}
Animal.__index = Animal
function Animal:new()
local obj = {}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print("Breathing...")
end
-- Dog herda de Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new()
local obj = {}
setmetatable(obj, Dog)
return obj
endAgora veja o que acontece quando criamos um Dog e chamamos o método da classe pai:
local buddy = Dog:new()
buddy:breathe() -- Saída: Respirando...A classe Dog nunca definiu :breathe(), mas ainda assim funciona. Lua primeiro verifica buddy, não encontra nada, então verifica Dog, ainda nada, e finalmente o encontra em Animal. Essa herança automática de métodos significa que você escreve o comportamento compartilhado uma vez no pai e cada classe filha se beneficia imediatamente.
Desafio
FácilVamos construir uma hierarquia simples de criaturas para ver a herança de métodos em ação! Você criará uma classe pai Animal e uma classe filha Dog, e então demonstrará que as instâncias de Dog podem usar métodos definidos apenas em Animal.
Você organizará seu código em três arquivos:
Animal.lua: Defina sua classe pai com o padrão de classe padrão. Inclua um construtor:new(name)que armazena o nome do animal e um método:speak()que imprime o nome do animal seguido pormakes a sound. Retorne a classe ao final do arquivo.Dog.lua: Defina sua classe filha que herda de Animal. Importe o módulo Animal e configure o link de herança para que Dog possa acessar os métodos de Animal. Inclua um construtor:new(name)que armazena o nome e define Dog como a metatabela. A classe Dog NÃO deve definir seu próprio método:speak()— ela herdará isso de Animal.main.lua: Importe seu módulo Dog, leia um nome da entrada, crie uma instância de Dog com esse nome e chame o método:speak()nela.
Você receberá uma entrada: o nome do cachorro.
Por exemplo, se a entrada for Buddy, a saída deve ser:
Buddy makes a soundA mágica aqui é que sua classe Dog nunca define :speak(), mas chamá-lo em uma instância de Dog funciona perfeitamente. Lua segue a cadeia de busca da instância de Dog para a classe Dog, e depois para a classe Animal, onde encontra o método. Isso é a herança em ação!
Folha de consulta
Instâncias de classes filhas ganham acesso automaticamente a todos os métodos da classe pai através da cadeia de busca do Lua. Quando um método é chamado em uma instância, o Lua pesquisa em cada tabela conectada até encontrar o método.
Configurando Herança
Definição da classe pai:
local Animal = {}
Animal.__index = Animal
function Animal:new()
local obj = {}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print("Breathing...")
endClasse filha com link de herança:
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new()
local obj = {}
setmetatable(obj, Dog)
return obj
endUsando Métodos Herdados
Instâncias filhas podem chamar métodos da classe pai mesmo que não estejam definidos na classe filha:
local buddy = Dog:new()
buddy:breathe() -- Saída: Breathing...A cadeia de busca: Lua verifica buddy → Dog → Animal até que o método seja encontrado.
Organização de Classes em Múltiplos Arquivos
Arquivo da classe pai (Animal.lua):
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:speak()
print(self.name .. " makes a sound")
end
return AnimalArquivo da classe filha (Dog.lua):
local Animal = require("Animal")
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = {name = name}
setmetatable(obj, Dog)
return obj
end
return DogUso no arquivo principal:
local Dog = require("Dog")
local buddy = Dog:new("Buddy")
buddy:speak() -- Saída: Buddy makes a soundExperimente você mesmo
-- main.lua: Ponto de entrada
local Dog = require('Dog')
-- Lê o nome do cachorro da entrada
local name = io.read()
-- TODO: Criar uma instância de Dog com o nome fornecido
-- TODO: Chamar o método :speak() na instância do cachorro
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Object Oriented Programming
1O Conceito 'Self'
Tabelas com Funções'self' ExplícitoA Sintaxe de Dois-pontosPonto vs Dois-pontosRecapitulação - Movendo o Ponto4Projeto: Banco Digital
Configuração do ProjetoMétodo de Depósito7Polimorfismo e Sobrescrita
Sobrescrita de MétodosChamando Métodos da Classe PaiDuck TypingInterface ComumVerificando o TipoRecapitulação - Papéis de Funcionários10Projeto: Gerenciador de Formas
Configuração do ProjetoClasse Retângulo2Padrão de Protótipo de Classe
O Conceito de ProtótipoVinculando com __indexO Construtor :new()Inicializando AtributosInstâncias IndependentesRecapitulação - Fábrica de Carros5Sobrecarga de Operadores em POO
Somando ObjetosSubtraindo ObjetosConcatenando ObjetosComparando Objetos (<, >)Recapitulação - Matemática de Carteira8Encapsulamento
Convenções de NomenclaturaClosures para PrivacidadeAcesso via ClosuresTabelas Somente LeituraLógica de ValidaçãoRecapitulação - Cofre Seguro11Padrões de Projeto (Lite)
Funções FactoryTabela SingletonPadrão IteratorObserver (Listener)Recapitulação - Logger Factory3Estado e Comportamento do Objeto
Variáveis de InstânciaMétodos GetterMétodos SetterPropriedades CalculadasFormatação de StringsVerificações de IgualdadeRecapitulação - Nota do Aluno6Fundamentos de Herança
Configurando a HerançaHerdando MétodosEstendendo o ConstrutorAdicionando Métodos FilhosCompartilhado vs ÚnicoRecapitulação - Hierarquia de Formas