Sobrescrita de Métodos
Parte da seção Programação Orientada a Objetos do Journey de Lua da Coddy. Lição 37 de 70.
Até agora, as classes child herdaram métodos da classe-pai e adicionaram novos. Mas e se uma classe child precisar do mesmo nome de método com comportamento diferente? Isso é chamado de substituição de método.
Quando você define um método em uma classe filha com o mesmo nome que um método na classe pai, a versão da classe filha tem prioridade. A cadeia de busca do Lua verifica primeiro a classe filha; se encontrar o método nela, para de procurar.
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 sobrescreve speak()
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()
print(self.name .. " barks: Woof!")
endAgora cada classe responde de forma diferente à mesma chamada de método:
local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")
generic:speak() -- Saída: Creature faz um som
buddy:speak() -- Saída: Buddy late: Woof!O :speak() de Dog substitui completamente a versão da classe pai para instâncias de Dog. Isso permite criar um comportamento especializado mantendo uma interface consistente: todo animal pode usar :speak(), mas cada espécie faz isso de uma maneira diferente.
Desafio
FácilVamos construir um pequeno reino animal onde diferentes criaturas falam de suas próprias maneiras únicas! Você criará uma classe pai Animal e duas classes filhas, Cat e Cow, que substituirão o método :speak() da classe pai, cada uma com seu próprio comportamento especializado.
Você organizará seu código em quatro arquivos:
Animal.lua: Sua classe base com um construtor:new(name)que armazena o nome do animal. Inclua um método:speak()que imprime o nome do animal seguido demakes a sound. Esse é o comportamento padrão que as classes filhas substituirão.Cat.lua: Uma classe filha que herda de Animal. Seu construtor:new(name)deve chamar o construtor da classe pai e, em seguida, vincular novamente a metatabela a Cat. Substitua o método:speak()para que os gatos digam algo diferente: imprima o nome do gato seguido demeows: Meow!Cow.lua: Outra classe filha que herda de Animal. Configure o construtor da mesma forma que em Cat. Substitua:speak()para que as vacas imprimam seu nome seguido demoos: Moo!main.lua: Junte tudo! Leia dois nomes da entrada, crie um Cat com o primeiro nome e um Cow com o segundo nome e, em seguida, chame:speak()em cada um para demonstrar que o mesmo nome de método produz uma saída diferente dependendo da classe.
Você receberá duas entradas:
- O nome do gato
- O nome da vaca
Em seu arquivo principal, crie os dois animais e chame :speak() primeiro no gato e depois na vaca.
Por exemplo, se as entradas forem Whiskers e Bessie, a saída deverá ser:
Whiskers meows: Meow!
Bessie moos: Moo!Observe como os dois animais respondem à mesma chamada do método :speak(), mas cada um produz uma saída específica para seu tipo. A versão de Cat substitui completamente o comportamento genérico da classe pai, "makes a sound", e o mesmo acontece com a de Cow. Isso é a substituição de métodos em ação: mesma interface, implementações diferentes!
Experimente você mesmo
-- main.lua: Reúna tudo
local Cat = require('Cat')
local Cow = require('Cow')
-- Ler a entrada
local catName = io.read()
local cowName = io.read()
-- TODO: Crie um Cat com o primeiro nome
-- TODO: Crie um Cow com o segundo nome
-- TODO: Chame :speak() no gato primeiro, depois na vaca
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
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ânguloClasse CírculoMétodo PerímetroColeção de FormasÁrea TotalFiltrar Formas2Padrã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 FormasPratique por conta própria: Compilador de Lua online