Menu
Coddy logo textTech

Somando Objetos

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

Você já viu como metamétodos como __tostring e __eq permitem que você personalize como os objetos se comportam. Agora vamos estender isso para operações aritméticas, começando com a adição.

O metamétodo __add define o que acontece quando você usa o operador + entre dois objetos. Quando o Lua vê a + b, ele procura por __add na metatabela de qualquer um dos operandos.

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    local obj = {x = x, y = y}
    setmetatable(obj, Vector)
    return obj
end

function Vector.__add(v1, v2)
    return Vector:new(v1.x + v2.x, v1.y + v2.y)
end

Observe que __add é definido com um ponto, não dois-pontos. Ele recebe ambos os operandos como argumentos e deve retornar um novo objeto em vez de modificar qualquer um dos originais. Isso mantém a operação previsível e segura.

local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b

print(c.x, c.y)  -- Saída: 4  6

A principal percepção é que __add deve estar na própria metatabela (aqui, Vector), não apenas no objeto. Como definimos Vector como a metatabela para todas as instâncias, todas elas compartilham esse comportamento automaticamente.

challenge icon

Desafio

Fácil

Vamos construir uma classe Vector que suporte a adição usando o operador +. Este é o seu primeiro passo na sobrecarga de operadores — fazendo com que seus objetos funcionem naturalmente com os operadores integrados do Lua.

Você organizará seu código em dois arquivos:

  • Vector.lua: Defina sua classe Vector com os componentes x e y. Inclua um construtor :new(x, y) e implemente o metamétodo __add para que a soma de dois vetores crie um novo vetor com os componentes combinados. Lembre-se de que __add usa a sintaxe de ponto (não dois-pontos) e recebe ambos os operandos como argumentos.
  • main.lua: Importe seu módulo Vector, crie instâncias de vetores e demonstre que somá-los produz o resultado correto.

Você receberá quatro entradas:

  1. Componente x do primeiro vetor
  2. Componente y do primeiro vetor
  3. Componente x do segundo vetor
  4. Componente y do segundo vetor

No seu arquivo principal, crie dois vetores com os componentes fornecidos, some-os usando o operador + e imprima os valores x e y do vetor resultante em linhas separadas.

Por exemplo, se as entradas forem 3, 4, 1, 2, a saída deve ser:

4
6

O primeiro vetor (3, 4) mais o segundo vetor (1, 2) é igual a um novo vetor (4, 6).

Folha de consulta

O metamétodo __add define o que acontece quando você usa o operador + entre dois objetos.

Quando o Lua vê a + b, ele procura por __add na metatabela de qualquer um dos operandos.

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    local obj = {x = x, y = y}
    setmetatable(obj, Vector)
    return obj
end

function Vector.__add(v1, v2)
    return Vector:new(v1.x + v2.x, v1.y + v2.y)
end

__add é definido com um ponto, não com dois-pontos. Ele recebe ambos os operandos como argumentos e deve retornar um novo objeto em vez de modificar qualquer um dos originais.

local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b

print(c.x, c.y)  -- Saída: 4  6

__add deve estar na própria metatabela, não apenas no objeto.

Experimente você mesmo

-- Requer o módulo Vector
local Vector = require('Vector')

-- Lê a entrada
local x1 = tonumber(io.read())
local y1 = tonumber(io.read())
local x2 = tonumber(io.read())
local y2 = tonumber(io.read())

-- TODO: Criar duas instâncias de Vector usando os valores de entrada

-- TODO: Somar os dois vetores usando o operador +

-- TODO: Imprimir os valores x e y do vetor resultante em linhas separadas
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