Adicionando Métodos Filhos
Parte da seção Object Oriented Programming do Journey de Lua da Coddy — lição 34 de 70.
A herança permite que as classes filhas acessem os métodos dos pais, mas o verdadeiro poder vem da adição de novos métodos que apenas o filho possui. Um Dog pode fazer tudo o que um Animal faz, além de coisas exclusivas de cães — como latir.
Adicionar um método específico para a classe filha é simples: basta defini-lo na tabela da classe filha. Como as instâncias procuram métodos em sua própria classe primeiro, elas encontrarão o novo método sem afetar a classe pai.
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print(self.name .. " is breathing")
end
-- Dog herda de Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
-- Novo método apenas em Dog
function Dog:bark()
print(self.name .. " says: Woof!")
endAgora as instâncias de Dog podem usar tanto métodos herdados quanto exclusivos:
local buddy = Dog:new("Buddy")
buddy:breathe() -- Saída: Buddy is breathing (herdado)
buddy:bark() -- Saída: Buddy says: Woof! (apenas do filho)A classe pai permanece inalterada—chamar :bark() em um Animal comum falharia, já que esse método não existe lá. É assim que a herança permite que você especialize o comportamento enquanto mantém a funcionalidade compartilhada em um único lugar.
Desafio
FácilVamos construir uma hierarquia de animais de estimação onde os gatos têm sua própria habilidade especial! Você criará uma classe pai Pet e uma classe filha Cat, onde Cat herda tudo de Pet, mas também possui um método único que apenas gatos podem fazer.
Você organizará seu código em três arquivos:
Pet.lua: Defina sua classe pai com um construtor:new(name)que armazena o nome do animal. Inclua um método:greet()que imprime o nome do animal seguido porsays hello. Configure o padrão de classe padrão e retorne a classe.Cat.lua: Defina sua classe filha que herda de Pet. O construtor:new(name)do seu Cat deve chamar o construtor pai para inicializar o nome e, em seguida, vincular novamente a metatabela ao Cat. Adicione um método:purr()específico da classe filha que imprime o nome do gato seguido porpurrs contentedly. Este método existe apenas em Cat—Pet não o possui!main.lua: Requeira seu módulo Cat, leia um nome da entrada, crie uma instância de Cat e demonstre que ela pode usar tanto o método herdado:greet()quanto seu próprio método único:purr().
Você receberá uma entrada: o nome do gato.
Em seu arquivo principal, crie um Cat com o nome fornecido, então chame :greet() seguido por :purr() em linhas separadas.
Por exemplo, se a entrada for Whiskers, a saída deve ser:
Whiskers says hello
Whiskers purrs contentedlyA primeira linha vem do método herdado :greet() definido em Pet, enquanto a segunda linha vem do método :purr() que existe apenas em Cat. Isso demonstra como as classes filhas podem fazer tudo o que seus pais fazem, além de seus próprios comportamentos especializados!
Folha de consulta
As classes filhas podem adicionar novos métodos que apenas elas possuem, enquanto ainda herdam todos os métodos da classe pai. As instâncias procuram métodos em sua própria classe primeiro e, em seguida, recorrem à classe pai.
Para adicionar um método específico da classe filha, defina-o na tabela da classe filha:
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print(self.name .. " is breathing")
end
-- Dog herda de Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
-- Método específico da classe filha
function Dog:bark()
print(self.name .. " says: Woof!")
endAs instâncias filhas podem usar tanto os métodos herdados quanto os exclusivos:
local buddy = Dog:new("Buddy")
buddy:breathe() -- Herdado de Animal
buddy:bark() -- Método exclusivo da classe filhaA classe pai permanece inalterada — ela não tem acesso aos métodos específicos da classe filha.
Experimente você mesmo
-- main.lua: Cria um Gato e demonstra herança
local Cat = require('Cat')
-- Lê o nome do gato da entrada
local name = io.read()
-- TODO: Cria uma instância de Gato com o nome fornecido
-- TODO: Chama o método herdado :greet() (de Pet)
-- TODO: Chama o método :purr() específico de Gato
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