Menu
Coddy logo textTech

Convenções de Nomenclatura

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

Em Lua, todos os campos de tabela são acessíveis publicamente por padrão. Qualquer pessoa pode ler ou modificar self.health diretamente. Embora o Lua não imponha privacidade, os programadores usam convenções de nomenclatura para comunicar a intenção — sinalizando quais campos devem ser tratados como detalhes de implementação interna.

A convenção padrão é prefixar campos privados com um underscore:

local Player = {}
Player.__index = Player

function Player:new(name)
    local obj = {
        name = name,      -- Público: tudo bem acessar diretamente
        _health = 100,    -- Privado: use métodos em vez disso
        _score = 0        -- Privado: rastreamento interno
    }
    setmetatable(obj, Player)
    return obj
end

function Player:getHealth()
    return self._health
end

function Player:takeDamage(amount)
    self._health = self._health - amount
end

O sublinhado não muda como o Lua funciona—player._health ainda é tecnicamente acessível. No entanto, ele serve como um aviso claro para outros programadores (e para o seu eu futuro): "Este campo deve ser privado. Em vez disso, acesse-o por meio de métodos."

Esta convenção é importante porque separa a interface (o que os outros devem usar) da implementação (como funciona internamente). Se mais tarde você precisar adicionar validação ou alterar como a saúde é armazenada, você apenas modifica os métodos — o código que usa :getHealth() continua funcionando sem alterações.

challenge icon

Desafio

Fácil

Vamos construir uma classe BankAccount que sinaliza adequadamente quais campos devem ser privados usando a convenção de nomenclatura com sublinhado (underscore)!

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

  • BankAccount.lua: Crie uma classe que gerencie as informações da conta. O construtor :new(ownerName, initialBalance) deve armazenar o nome do proprietário como um campo público (owner) e o saldo como um campo privado (_balance). Inclua três métodos:
    • :getBalance() — retorna o saldo atual
    • :deposit(amount) — adiciona o valor ao _balance
    • :getOwner() — retorna o nome do proprietário
  • main.lua: Importe seu módulo BankAccount, leia o nome do proprietário, o saldo inicial e o valor do depósito a partir da entrada. Crie uma conta, realize um depósito e, em seguida, imprima o proprietário e o saldo final.

Você receberá três entradas:

  1. O nome do proprietário
  2. O saldo inicial (um número)
  3. O valor do depósito (um número)

Sua saída deve ter duas linhas mostrando o proprietário e o saldo final após o depósito:

Owner: {ownerName}
Balance: {finalBalance}

Por exemplo, se as entradas forem Maria, 500 e 150, a saída deve ser:

Owner: Maria
Balance: 650

Lembre-se: o prefixo de sublinhado em _balance sinaliza para outros programadores que este campo deve ser acessado por meio de métodos como :getBalance() e :deposit(), não diretamente. O campo owner sem o sublinhado indica que não há problemas em acessá-lo publicamente.

Folha de consulta

Em Lua, todos os campos de uma tabela são acessíveis publicamente por padrão. Para comunicar quais campos devem ser tratados como detalhes de implementação interna, use a convenção de nomenclatura com sublinhado prefixando campos privados com um sublinhado (_).

O sublinhado não impõe privacidade — é um sinal para outros programadores de que o campo deve ser acessado por meio de métodos em vez de diretamente.

local Player = {}
Player.__index = Player

function Player:new(name)
    local obj = {
        name = name,      -- Público: tudo bem acessar diretamente
        _health = 100,    -- Privado: use métodos em vez disso
        _score = 0        -- Privado: rastreamento interno
    }
    setmetatable(obj, Player)
    return obj
end

function Player:getHealth()
    return self._health
end

function Player:takeDamage(amount)
    self._health = self._health - amount
end

Esta convenção separa a interface (o que os outros devem usar) da implementação (como funciona internamente), tornando o código mais fácil de manter quando mudanças são necessárias.

Experimente você mesmo

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

-- Lê as entradas
local ownerName = io.read()
local initialBalance = tonumber(io.read())
local depositAmount = tonumber(io.read())

-- TODO: Criar uma nova BankAccount com ownerName e initialBalance

-- TODO: Realizar um depósito usando o depositAmount

-- TODO: Imprimir o proprietário e o saldo final no formato exigido
-- Formato:
-- Owner: {ownerName}
-- Balance: {finalBalance}
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