Menu
Coddy logo textTech

Configurando a Herança

Parte da seção Programação Orientada a Objetos do Journey de Lua da Coddy. Lição 31 de 70.

Até agora, você criou classes nas quais cada objeto procura métodos em uma única tabela de protótipo. Mas e se você quiser que uma classe seja construída com base em outra? É aí que entra a herança: uma classe filha pode acessar tudo de uma classe pai e, ao mesmo tempo, adicionar seus próprios recursos.

A principal percepção é que a própria tabela de uma classe pode ter uma metatabela. Quando o Lua não consegue encontrar algo na classe filha, ele procura no __index da metatabela da classe filha, que aponta para a classe pai.

-- Classe pai
local Animal = {}
Animal.__index = Animal

function Animal:new()
    local obj = {}
    setmetatable(obj, Animal)
    return obj
end

function Animal:breathe()
    print("Breathing...")
end

Agora, veja a configuração da herança. Criamos uma classe filha e definimos sua metatabela para consultar a classe pai:

-- Classe filha
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

Esta única linha, setmetatable(Dog, {__index = Animal}), cria o vínculo de herança. Quando uma instância de Dog chama um método não encontrado em Dog, Lua verifica Animal.

A cadeia de busca funciona assim: instance → Dog → Animal. Cada etapa usa __index para encontrar a próxima tabela a ser pesquisada. Isso permite que as classes filhas herdem automaticamente todos os métodos das classes pai sem copiá-los.

challenge icon

Desafio

Fácil

Vamos construir sua primeira hierarquia de herança! Você criará uma relação simples de classe pai e filha, na qual uma classe Machine servirá como base, e uma classe Robot herdará dela.

Você organizará seu código em três arquivos:

  • Machine.lua: Defina sua classe pai usando o padrão de classe comum. Inclua um construtor :new() e um método :status() que imprime Machine is operational. Não se esqueça de configurar __index e retornar a classe ao final do arquivo.
  • Robot.lua: Defina sua classe filha, que herda de Machine. Importe o módulo Machine, configure a tabela Robot com seu próprio __index e estabeleça o vínculo de herança usando setmetatable(Robot, {__index = Machine}). Inclua um construtor :new() que crie uma instância com Robot como sua metatabela.
  • main.lua: Reúna tudo importando seu módulo Robot, criando uma instância de Robot e chamando o método herdado :status().

O conceito principal aqui é que sua classe Robot não define :status() por si mesma. Ela herda esse método de Machine por meio da cadeia de metatabelas. Quando você chama :status() em uma instância de Robot, Lua procurará primeiro em Robot, não o encontrará e, em seguida, seguirá o vínculo __index até Machine, onde descobrirá o método.

Sua saída deve ser:

Machine is operational

Essa única linha prova que a herança está funcionando. Seu Robot acessou com sucesso um método definido apenas em sua classe pai!

Experimente você mesmo

-- main.lua: Reúna tudo

-- TODO: Requeira o módulo Robot

-- TODO: Crie uma instância de Robot usando Robot:new()

-- TODO: Chame o método herdado :status() na sua instância de robot
-- This should print "Machine is operational"
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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de Lua online