9 Classes e objetos
Reunir estado, comportamento e invariantes
9.1 Objetivos de aprendizagem
Ao concluir este capítulo, você deverá ser capaz de:
- diferenciar classe, objeto, atributo e método;
- inicializar objetos com construtores;
- usar
thispara distinguir atributo e parâmetro; - proteger o estado com
private; - representar regras por operações, não por setters genéricos.
9.2 Estado e comportamento
Uma classe define a estrutura e as operações disponíveis. Um objeto é uma instância concreta dessa classe. Seus atributos formam o estado; seus métodos definem comportamentos.
class ContaPontos {
private int saldo;
public ContaPontos(int saldoInicial) {
if (saldoInicial < 0) {
throw new IllegalArgumentException("Saldo inicial inválido.");
}
this.saldo = saldoInicial;
}
public void creditar(int valor) {
if (valor <= 0) {
throw new IllegalArgumentException("O crédito deve ser positivo.");
}
saldo += valor;
}
public boolean debitar(int valor) {
if (valor <= 0 || valor > saldo) {
return false;
}
saldo -= valor;
return true;
}
public int getSaldo() {
return saldo;
}
}A validação de valor <= 0 é indispensável: sem ela, subtrair um valor negativo aumentaria o saldo. O atributo privado só pode mudar por operações que preservam as regras.
9.3 Construtores e this
O construtor cria um estado inicial válido. this.nome indica o atributo do objeto atual, enquanto nome representa o parâmetro:
final impede que a referência seja reatribuída depois da construção.
9.4 Classe do chatbot
import java.util.ArrayList;
import java.util.List;
class ChatbotBasico {
private final String nome;
private final List<String> historico = new ArrayList<>();
ChatbotBasico(String nome) {
if (nome == null || nome.isBlank()) {
throw new IllegalArgumentException("Nome obrigatório.");
}
this.nome = nome.strip();
}
String responder(String mensagem) {
if (mensagem == null || mensagem.isBlank()) {
return "Digite uma mensagem.";
}
historico.add(mensagem.strip());
return nome + ": recebi sua mensagem.";
}
List<String> consultarHistorico() {
return List.copyOf(historico);
}
}
public class Capitulo08Classes {
public static void main(String[] args) {
ChatbotBasico bot = new ChatbotBasico("TutorJavaBot");
System.out.println(bot.responder("oi"));
System.out.println(bot.consultarHistorico());
}
}A cópia devolvida por consultarHistorico impede alteração externa da lista interna.
9.5 Composição inicial
Composição representa uma relação “tem um”. Um chatbot pode ter um objeto responsável pelo histórico; uma turma pode ter uma lista de alunos. Quando a responsabilidade crescer, mover o histórico para uma classe própria evita que o chatbot concentre trabalho demais.
9.6 Evolução do projeto: versão 8
Transforme variáveis e métodos isolados em um objeto ChatbotBasico. O main cria o objeto e coordena entrada e saída; a classe protege nome, histórico e regras de resposta.
O exemplo completo está em examples/src/Capitulo08Classes.java.
9.7 Prática verificável
- Acrescente o método
totalMensagens(). - Rejeite nomes vazios no construtor.
- Confirme que a lista devolvida não pode alterar o histórico interno.
- Explique qual invariante cada validação protege.
Uma invariante é uma condição que deve permanecer verdadeira durante toda a vida do objeto, como “o nome do chatbot não é vazio”.