Menu
Coddy logo textTech

Sobrescrita de Métodos

Parte da seção Object Oriented Programming do Journey de Lua da Coddy — lição 37 de 70.

Até agora, as classes filhas herdaram métodos das classes pai e adicionaram novos. Mas e se uma classe filha precisar do mesmo nome de método com um comportamento diferente? Isso é chamado de method overriding (sobrescrita de método).

Quando você define um método em uma classe filha com o mesmo nome de um na classe pai, a versão da filha tem prioridade. A cadeia de busca do Lua verifica a classe filha primeiro — se encontrar o método lá, ela 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!")
end

Agora 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() do Dog substitui completamente a versão do pai para instâncias de Dog. Isso permite que você crie um comportamento especializado enquanto mantém uma interface consistente — cada animal pode :speak(), mas cada espécie o faz de forma diferente.

challenge icon

Desafio

Fácil

Vamos 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 substituem o método :speak() do pai por 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 por makes a sound. Este é o comportamento padrão que as classes filhas irão sobrescrever.
  • Cat.lua: Uma classe filha que herda de Animal. Seu construtor :new(name) deve chamar o construtor pai e, em seguida, vincular novamente a metatabela para Cat. Sobrescreva o método :speak() para que os gatos digam algo diferente—imprima o nome do gato seguido por meows: Meow!
  • Cow.lua: Outra classe filha que herda de Animal. Configure o construtor da mesma forma que Cat. Sobrescreva :speak() para que as vacas imprimam seu nome seguido por moos: Moo!
  • main.lua: Reúna tudo! Leia dois nomes da entrada, crie um Cat com o primeiro nome e uma Cow com o segundo nome, então chame :speak() em cada um para demonstrar que o mesmo nome de método produz saídas diferentes dependendo da classe.

Você receberá duas entradas:

  1. O nome do gato
  2. O nome da vaca

No seu arquivo principal, crie ambos os animais e chame :speak() primeiro no gato e depois na vaca.

Por exemplo, se as entradas forem Whiskers e Bessie, a saída deve ser:

Whiskers meows: Meow!
Bessie moos: Moo!

Observe como ambos os animais respondem à mesma chamada de método :speak(), mas cada um produz uma saída específica para o seu tipo. A versão do Cat substitui completamente o comportamento genérico "makes a sound" do pai, assim como a do Cow. Isso é a sobrescrita de método em ação—mesma interface, implementações diferentes!

Folha de consulta

A sobreposição de métodos (method overriding) permite que uma classe filha defina um método com o mesmo nome de um método pai, substituindo o comportamento do pai por uma funcionalidade especializada.

Quando o Lua procura por um método, ele verifica primeiro a classe filha. Se encontrar o método lá, ele usa essa versão e para de procurar na classe pai.

Exemplo básico de sobreposição de métodos:

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 overrides 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!")
end

Usando o método sobreposto:

local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")

generic:speak()  -- Output: Creature makes a sound
buddy:speak()    -- Output: Buddy barks: Woof!

O método da classe filha substitui completamente a versão do pai para instâncias dessa classe filha, permitindo um comportamento especializado enquanto mantém uma interface consistente em todas as classes.

Experimente você mesmo

-- main.lua: Reúne tudo

local Cat = require('Cat')
local Cow = require('Cow')

-- Ler entrada
local catName = io.read()
local cowName = io.read()

-- TODO: Criar um Cat com o primeiro nome

-- TODO: Criar um Cow com o segundo nome

-- TODO: Chamar :speak() no gato primeiro, depois na vaca
quiz iconTeste seus conhecimentos

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