Ao estudar OOP, você ouve “encapsulamento” centenas de vezes, mas quando alguém pergunta “Então, como fazer isso no código?”, é comum ficar sem palavras. Você entende o conceito, mas não sabe por onde começar a escrever.
Em resumo, encapsulamento é esconder os dados internos de um objeto para impedir alterações arbitrárias externas e permitir acesso apenas por caminhos definidos. No Swift, isso é implementado com modificadores de acesso.
Hoje veremos em código real os cinco níveis de controle de acesso, incluindo private e internal, e entenderemos como o ocultamento de informações protege o código.
O que exatamente é encapsulamento?
Encapsulamento (Encapsulation) é uma das quatro características fundamentais de OOP.
Em uma frase:
Agrupar os dados e as funções que os manipulam, ocultar o interior e expor apenas o necessário.
Por que ocultar?
Pense em uma conta bancária. Seria um desastre se qualquer pessoa pudesse alterar diretamente o saldo para qualquer número.
Depósitos e saques precisam seguir procedimentos definidos, garantindo regras como “não é possível sacar mais do que o saldo”.
Impedir o acesso direto aos valores internos e abrir apenas caminhos validados é chamado de ocultamento de informações.
Se encapsulamento é o conceito mais amplo, ocultamento de informações é o princípio central que o torna possível.
Comparação rápida dos cinco níveis de acesso do Swift
O Swift divide o escopo de acesso em cinco níveis, organizados aqui do mais restrito ao mais amplo.
(Com base na sintaxe mais recente do Swift em 2026.)
| Modificador de acesso | Escopo acessível | Uso principal |
|---|---|---|
private |
Dentro do bloco de chaves da declaração | Estado interno que você realmente quer ocultar |
fileprivate |
Todo o mesmo arquivo-fonte | Tipos colaboradores no mesmo arquivo |
internal |
Todo o mesmo módulo (app/framework) | Valor padrão; a maior parte do código |
public |
Também pode ser usado de outros módulos | API pública fora da biblioteca |
open |
Permite herança e sobrescrita a partir de outros módulos | Pontos de extensão de framework |
Há um ponto importante para lembrar.
Se você não adicionar nada, internal será o padrão.
Por isso o código funcionava normalmente dentro do mesmo app mesmo sem você escrever um modificador de acesso.
A diferença entre public e open também confunde facilmente. Em outro módulo, apenas open permite herança e sobrescrita. public pode ser usado, mas não permite herança.
Obtendo ocultamento real de informações com private
Vamos ver o exemplo de uma conta no código; só explicar em palavras não é suficiente.
Começaremos com um exemplo ruim, sem encapsulamento.
class BadAccount {
var balance: Int = 0 // Qualquer pessoa pode modificar externamente
}
let acc = BadAccount()
acc.balance = -99999 // Até valores absurdos entram sem validação
print(acc.balance)
// Saída: -99999
Saldo negativo de 90 mil? As regras desmoronaram completamente.
Agora vamos ocultar o estado interno com private e deixar abertas apenas as rotas de depósito e saque.
class Account {
private var balance: Int = 0 // Bloquear acesso externo
func deposit(_ amount: Int) {
guard amount > 0 else { return }
balance += amount
}
func withdraw(_ amount: Int) -> Bool {
guard amount > 0, balance >= amount else { return false }
balance -= amount
return true
}
var currentBalance: Int { balance } // Permitir apenas leitura
}
let myAccount = Account()
myAccount.deposit(10000)
print(myAccount.withdraw(30000)) // Saldo insuficiente
// Saída: false
Agora balance não pode ser alterado diretamente de fora.
Um código como myAccount.balance = -99999 gera um erro de compilação.
O dinheiro só pode circular por deposit e withdraw, que contêm as regras de validação.
Esse é o poder do ocultamento de informações: impedir desde o início que seja escrito código que viole as regras.
private(set) — permitir leitura e bloquear apenas a escrita
Vamos avançar para um caso mais prático.
É muito comum querer permitir a leitura externa de um valor, mas bloquear apenas sua alteração.
Você pode criar uma propriedade computada separada, como acima, mas o Swift oferece uma opção mais limpa.
class ScoreBoard {
private(set) var score: Int = 0 // Leitura public, Escrita private
func addPoint() {
score += 10
}
}
let board = ScoreBoard()
board.addPoint()
print(board.score) // Leitura liberada
// Saída: 10
// board.score = 999 // Esta linha gera um erro de compilação
Ao adicionar private(set), a leitura continua pública, enquanto a permissão de escrita fica restrita ao interior.
Como a pontuação só pode aumentar por meio de addPoint(), você evita que a lógica externa do jogo a manipule.
Uso muito essa sintaxe porque não é preciso criar uma propriedade computada.
Quando usar cada modificador?
Veja os critérios mais úteis para quando surgir dúvida no trabalho.
- Comece por
private. Ampliar o escopo quando necessário é mais seguro do que deixá-lo aberto e restringir depois. - O valor padrão
internalfunciona bem na maioria dos apps. Não é preciso escrever tudo explicitamente. public·opensó precisam ser considerados ao criar bibliotecas ou frameworks para outras pessoas.- Use
opensomente quando quiser permitir também herança. Caso contrário,publicé suficiente.
| Situação | Decisão |
|---|---|
| Variável de estado usada apenas internamente | private |
| Você quer permitir somente leitura externa | private(set) |
| Livremente dentro do mesmo app | internal (padrão) |
| Expor publicamente como biblioteca | public |
| Permitir herança e sobrescrita externa | open |
Lembre-se de uma coisa: o escopo de acesso deve ser aberto sempre da forma mais restrita possível.
Como isso aparece em entrevistas
P. Qual é a diferença entre encapsulamento e ocultamento de informações?
Encapsulamento é o conceito de design que reúne dados e métodos em um objeto, enquanto ocultamento de informações é o princípio de esconder a implementação interna do exterior. Uma resposta clara é que encapsulamento é o recipiente maior, e o ocultamento de informações é realizado dentro dele por meio de modificadores de acesso.
P. Qual é a diferença entre public e open no Swift?
Ambos podem ser acessados de outros módulos, mas apenas open permite herança e sobrescrita de métodos a partir de um módulo externo. Classes public podem ser usadas externamente, mas não herdadas. Vale acrescentar que open é usado somente para abrir pontos de extensão de um framework.
Os modificadores de acesso podem parecer apenas algumas regras de sintaxe para memorizar, mas na verdade treinam o raciocínio de projetar quem pode alterar determinado valor.
Digite você mesmo o exemplo da conta e tudo ficará claro. Recomendo começar adicionando private em um projeto pequeno!

