Java POO Básico
Encapsulamento
Encapsulamento é o princípio de esconder o estado interno de um objeto e expor apenas o que ele precisa mostrar. Em Java, isso é feito com modificadores de acesso (private, protected, public) aplicados a atributos e métodos. A ideia é que ninguém de fora consiga alterar o estado de um objeto de forma inválida.
Quando um atributo é private, o acesso externo só acontece por meio de getters e setters. Isso permite validar valores antes de gravar, garantindo que o objeto nunca entre em um estado inconsistente — o que chamamos de invariante. Por exemplo, uma conta bancária não deveria ter saldo negativo se isso não faz sentido para o domínio.
Um passo além é a imutabilidade: se um objeto não muda depois de criado, ele é seguro para compartilhar entre threads e mais fácil de raciocinar. Em Java, isso é obtido com atributos private final, sem setters, e com cópias defensivas de objetos mutáveis recebidos ou devolvidos.
Neste card, vamos ver como encapsular uma classe Conta, proteger seu saldo com validações e, por fim, criar uma versão imutável usando final e ausência de setters.
Pontos-chave
privateesconde o atributo;publicexpõe apenas o que faz parte da API da classe.- Setters permitem validar valores e manter invariantes, como
saldo >= 0. - Getters não devem vazar referências internas mutáveis; devolva cópias quando necessário.
- Imutabilidade combina
private final, ausência de setters e cópias defensivas. - Encapsular não é só gerar getters/setters: é decidir quais operações fazem sentido para o domínio.
public class ContaBancaria {
private final String titular; // final: não muda após o construtor
private double saldo; // privado: só acessível dentro da classe
public ContaBancaria(String titular, double saldoInicial) {
if (titular == null || titular.isBlank()) {
throw new IllegalArgumentException("titular obrigatório");
}
if (saldoInicial < 0) {
throw new IllegalArgumentException("saldo inicial não pode ser negativo");
}
this.titular = titular;
this.saldo = saldoInicial;
}
public String getTitular() { return titular; }
public double getSaldo() { return saldo; }
public void depositar(double valor) {
if (valor <= 0) throw new IllegalArgumentException("valor deve ser positivo");
saldo += valor;
}
public void sacar(double valor) {
if (valor <= 0) throw new IllegalArgumentException("valor deve ser positivo");
if (valor > saldo) throw new IllegalStateException("saldo insuficiente");
saldo -= valor;
}
public static void main(String[] args) {
ContaBancaria c = new ContaBancaria("Ana", 100.0);
c.depositar(50.0);
c.sacar(30.0);
System.out.println(c.getTitular() + ": " + c.getSaldo());
// c.saldo = -999; // erro de compilação: saldo é private
}
}