Encapsulamento significa agrupar dados e os métodos que operam neles dentro de uma unidade (uma classe) e ocultar o estado interno atrás de uma interface pública controlada. Os chamadores interagem através de métodos, não mexendo diretamente em campos brutos.
Por que isso importa
Se alguém puder alterar um campo diretamente, você nunca poderá garantir que o objeto permaneça válido. O encapsulamento permite que a classe implemente seus próprios invariantes.
public class Account {
private double balance; // hidden: no direct access
public void withdraw(double amount) {
if (amount <= 0) // guard the invariant
throw new IllegalArgumentException("amount must be positive");
if (amount > balance)
throw new IllegalStateException("insufficient funds");
balance -= amount; // only valid changes get through
}
public double getBalance() { return balance; }
}
// Without encapsulation, this would be possible and disastrous:
account.balance = -5000; // bypasses every rule
Porque balance é privado, o único caminho para alterá-lo passa por withdraw, que protege as regras.
Armadilha
Encapsulamento não é "adicione um getter/setter para cada campo". Expor um setter para tudo é pouco melhor do que campos públicos. Exponha comportamento, não estado bruto.
Por que isso importa
O encapsulamento mantém invariantes em um só lugar, então um bug na manipulação de saldo só pode existir dentro de Account, não espalhado por toda a base de código.
Também permite alterar a representação interna depois (armazenar centavos como um inteiro, adicionar logging) sem quebrar os chamadores, porque eles dependem apenas da interface pública.
