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
endO 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.
Desafio
FácilVamos 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:
- O nome do proprietário
- O saldo inicial (um número)
- 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: 650Lembre-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
endEsta 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}
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
1O Conceito 'Self'
Tabelas com Funções'self' ExplícitoA Sintaxe de Dois-pontosPonto vs Dois-pontosRecapitulação - Movendo o Ponto4Projeto: Banco Digital
Configuração do ProjetoMétodo de Depósito7Polimorfismo e Sobrescrita
Sobrescrita de MétodosChamando Métodos da Classe PaiDuck TypingInterface ComumVerificando o TipoRecapitulação - Papéis de Funcionários10Projeto: Gerenciador de Formas
Configuração do ProjetoClasse Retângulo2Padrão de Protótipo de Classe
O Conceito de ProtótipoVinculando com __indexO Construtor :new()Inicializando AtributosInstâncias IndependentesRecapitulação - Fábrica de Carros5Sobrecarga de Operadores em POO
Somando ObjetosSubtraindo ObjetosConcatenando ObjetosComparando Objetos (<, >)Recapitulação - Matemática de Carteira8Encapsulamento
Convenções de NomenclaturaClosures para PrivacidadeAcesso via ClosuresTabelas Somente LeituraLógica de ValidaçãoRecapitulação - Cofre Seguro11Padrões de Projeto (Lite)
Funções FactoryTabela SingletonPadrão IteratorObserver (Listener)Recapitulação - Logger Factory3Estado e Comportamento do Objeto
Variáveis de InstânciaMétodos GetterMétodos SetterPropriedades CalculadasFormatação de StringsVerificações de IgualdadeRecapitulação - Nota do Aluno6Fundamentos de Herança
Configurando a HerançaHerdando MétodosEstendendo o ConstrutorAdicionando Métodos FilhosCompartilhado vs ÚnicoRecapitulação - Hierarquia de Formas