Chamando Métodos da Classe Pai
Parte da seção Object Oriented Programming do Journey de Lua da Coddy — lição 38 de 70.
Às vezes, sobrescrever um método completamente não é o que você deseja. Em vez disso, você pode querer estender o comportamento do pai — fazer o que o pai faz e, em seguida, adicionar algo extra. Para conseguir isso, você pode chamar o método pai diretamente de dentro da sobrescrita do filho.
A técnica utiliza a sintaxe de ponto com o nome da classe pai, passando explicitamente self como o primeiro argumento:
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
-- Dog estende o comportamento pai
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
function Dog:speak()
Animal.speak(self) -- Chama o método pai primeiro
print(self.name .. " wags tail happily")
endA linha principal é Animal.speak(self). Ao usar a sintaxe de ponto na classe pai e passar self manualmente, invocamos o método original antes de adicionar nosso próprio comportamento:
local buddy = Dog:new("Buddy")
buddy:speak()
-- Saída:
-- Buddy faz um som
-- Buddy balança o rabo alegrementeEste padrão é útil quando o método pai realiza um trabalho importante que você não deseja duplicar. O filho pode executar a lógica do pai primeiro, por último ou até mesmo no meio de seu próprio código — oferecendo controle total sobre como os comportamentos se combinam.
Desafio
FácilVamos construir um sistema de saudação onde uma FormalPerson estende o comportamento de uma Person comum! Em vez de substituir completamente a forma como uma pessoa se apresenta, a versão formal fará primeiro a apresentação padrão e depois adicionará um toque extra de polidez.
Você organizará seu código em três arquivos:
Person.lua: Sua classe base com um construtor:new(name)que armazena o nome da pessoa. Inclua um método:introduce()que imprime o nome da pessoa seguido desays hi. Este é o comportamento base que será estendido.FormalPerson.lua: Uma classe filha que herda de Person. Seu construtor deve chamar o construtor pai para lidar com o nome. Sobrescreva o método:introduce(), mas em vez de substituir inteiramente o comportamento do pai, chame o método do pai primeiro usandoPerson.introduce(self), e então imprima uma linha adicional com o nome da pessoa seguido debows politely.main.lua: Importe seu módulo FormalPerson, leia um nome da entrada, crie uma instância de FormalPerson e chame:introduce()para ver ambos os comportamentos combinados.
Você receberá uma entrada: o nome da pessoa.
Quando você chamar :introduce() em uma FormalPerson, ela deve produzir duas linhas de saída — a primeira do método do pai, a segunda da adição da filha:
{name} says hi
{name} bows politelyPor exemplo, se a entrada for Eleanor, a saída deve ser:
Eleanor says hi
Eleanor bows politelyA ideia principal aqui é que a FormalPerson não duplica a lógica "says hi" — ela delega esse trabalho ao método pai e, em seguida, adiciona seu próprio comportamento exclusivo por cima. Isso mantém seu código limpo e demonstra como as classes filhas podem estender, em vez de substituir, a funcionalidade do pai!
Folha de consulta
Para estender o comportamento de um método pai em vez de substituí-lo completamente, chame o método pai de dentro da substituição do filho usando a sintaxe de ponto e passando explicitamente o self:
function ChildClass:method()
ParentClass.method(self) -- Chama o método pai
-- Adiciona comportamento adicional
endExemplo completo mostrando a extensão de método:
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
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
function Dog:speak()
Animal.speak(self) -- Executa o comportamento do pai primeiro
print(self.name .. " wags tail happily") -- Adiciona o comportamento do filho
end
local buddy = Dog:new("Buddy")
buddy:speak()
-- Output:
-- Buddy makes a sound
-- Buddy wags tail happilyO método pai pode ser chamado em qualquer ponto: antes, depois ou no meio da própria lógica do filho, oferecendo controle total sobre como os comportamentos se combinam.
Experimente você mesmo
-- main.lua: Ponto de entrada para o sistema de saudação
local FormalPerson = require('FormalPerson')
-- Lê o nome da pessoa a partir da entrada
local name = io.read()
-- TODO: Criar uma instância de FormalPerson com o nome fornecido
-- TODO: Chamar o método introduce na instância de FormalPerson
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