Menu
Coddy logo textTech

Variáveis de Instância

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

Bem-vindo a um novo capítulo focado em como os objetos gerenciam seus dados internos. Você aprendeu a criar classes e instâncias — agora é hora de explorar como cada instância armazena e gerencia seu próprio estado único.

Variáveis de instância são campos que pertencem exclusivamente a um único objeto. Quando você atribui um valor a self.something dentro de um método ou construtor, esses dados residem apenas naquela instância específica. Outros objetos da mesma classe possuem suas próprias cópias separadas.

Isso se torna especialmente importante ao armazenar dados complexos, como tabelas. Considere um sistema de inventário onde cada personagem carrega itens diferentes:

local Inventory = {}
Inventory.__index = Inventory

function Inventory:new()
    local instance = {}
    setmetatable(instance, self)
    instance.items = {}  -- Cada instância recebe sua própria tabela vazia
    return instance
end

function Inventory:addItem(item)
    table.insert(self.items, item)
end

A linha principal é instance.items = {}. Ao criar uma nova tabela vazia dentro do construtor, cada objeto de inventário recebe sua própria lista distinta. Se, em vez disso, você definisse items na própria tabela da classe, todas as instâncias acidentalmente compartilhariam a mesma tabela — adicionar uma espada a um personagem a daria a todos!

local bag1 = Inventory:new()
local bag2 = Inventory:new()

bag1:addItem("Sword")
bag2:addItem("Potion")

print(#bag1.items)  -- Saída: 1
print(#bag2.items)  -- Saída: 1

Cada inventário mantém sua própria coleção. Este padrão se aplica sempre que uma instância precisa rastrear dados que mudam de forma independente — listas, contadores ou qualquer estado mutável exclusivo desse objeto.

challenge icon

Desafio

Fácil

Vamos construir um sistema de ShoppingCart onde cada carrinho mantém sua própria lista separada de produtos. Isso demonstrará como as variáveis de instância mantêm os dados isolados entre os objetos — adicionar itens a um carrinho não afetará o outro!

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

  • ShoppingCart.lua: Defina sua classe ShoppingCart onde cada instância tem sua própria tabela products. Inclua:
    • Um construtor :new() que inicializa uma lista de produtos vazia para cada carrinho
    • Um método :addProduct(productName) que adiciona um produto à lista deste carrinho
    • Um método :listProducts() que imprime cada produto em uma linha separada
  • main.lua: Requeira seu módulo ShoppingCart e crie dois carrinhos separados. Adicione produtos diferentes a cada carrinho para provar que eles mantêm inventários independentes.

Você receberá quatro entradas:

  1. Primeiro produto para adicionar ao carrinho A
  2. Segundo produto para adicionar ao carrinho A
  3. Primeiro produto para adicionar ao carrinho B
  4. Segundo produto para adicionar ao carrinho B

No seu arquivo principal:

  1. Crie dois carrinhos de compras: cartA e cartB
  2. Adicione os dois primeiros produtos ao cartA
  3. Adicione os dois últimos produtos ao cartB
  4. Imprima Cart A: e depois liste os produtos do carrinho A
  5. Imprima Cart B: e depois liste os produtos do carrinho B

Por exemplo, se as entradas forem Apple, Bread, Milk e Eggs, a saída deve ser:

Cart A:
Apple
Bread
Cart B:
Milk
Eggs

Lembre-se: a chave é inicializar products como uma nova tabela vazia dentro do construtor. Isso garante que cada instância de carrinho receba sua própria lista separada, em vez de compartilhar uma única tabela entre todos os carrinhos.

Folha de consulta

Variáveis de instância são campos que pertencem exclusivamente a um único objeto. Quando você atribui um valor a self.something dentro de um método ou construtor, esses dados vivem apenas naquela instância específica.

Para criar variáveis de instância, inicialize-as dentro do construtor usando uma nova tabela para cada instância:

local Inventory = {}
Inventory.__index = Inventory

function Inventory:new()
    local instance = {}
    setmetatable(instance, self)
    instance.items = {}  -- Cada instância recebe sua própria tabela vazia
    return instance
end

function Inventory:addItem(item)
    table.insert(self.items, item)
end

A chave é instance.items = {}—criar uma nova tabela vazia dentro do construtor garante que cada objeto receba seus próprios dados distintos. Se você definisse items na própria tabela da classe, todas as instâncias compartilhariam a mesma tabela.

local bag1 = Inventory:new()
local bag2 = Inventory:new()

bag1:addItem("Sword")
bag2:addItem("Potion")

print(#bag1.items)  -- Output: 1
print(#bag2.items)  -- Output: 1

Cada instância mantém sua própria coleção de forma independente. Este padrão se aplica a qualquer estado mutável exclusivo de um objeto—listas, contadores ou outros dados que mudam por instância.

Experimente você mesmo

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

-- Lê as entradas
local product1 = io.read()
local product2 = io.read()
local product3 = io.read()
local product4 = io.read()

-- TODO: Criar dois carrinhos de compras: cartA e cartB

-- TODO: Adicionar product1 e product2 ao cartA

-- TODO: Adicionar product3 e product4 ao cartB

-- TODO: Imprimir "Cart A:" e depois listar os produtos do cartA

-- TODO: Imprimir "Cart B:" e depois listar os produtos do cartB
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