Médio Java
Conta com invariante de saldo
Enunciado
Implemente a classe Conta com titular (String) e saldo (double) privados. O saldo nunca pode ficar negativo. Forneça depositar(double) e sacar(double) que lancem IllegalArgumentException para valores não positivos e IllegalStateException quando o saque exceder o saldo.
Requisitos
titularesaldosãoprivate.depositarrejeita valores<= 0comIllegalArgumentException.sacarrejeita valores<= 0comIllegalArgumentExceptione valores maiores que o saldo comIllegalStateException.- O
maindemonstra um depósito, um saque e captura uma tentativa inválida.
Código inicial
public class Conta {
private String titular;
private double saldo;
public Conta(String titular, double saldoInicial) {
// TODO: valide e atribua
}
public String getTitular() { return titular; }
public double getSaldo() { return saldo; }
// TODO: depositar e sacar com validações
public static void main(String[] args) {
// TODO: demonstre depósito, saque e uma tentativa inválida
}
}
Saída esperada
Saldo: 120.0
Tentativa inválida: saldo insuficiente
Ver dica
Use throw new IllegalStateException("saldo insuficiente"); quando valor > saldo.
Mostrar solução
public class Conta {
private String titular;
private double saldo;
public Conta(String titular, double saldoInicial) {
if (titular == null || titular.isBlank()) {
throw new IllegalArgumentException("titular obrigatório");
}
if (saldoInicial < 0) {
throw new IllegalArgumentException("saldo inicial inválido");
}
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) {
Conta c = new Conta("Ana", 100.0);
c.depositar(50.0);
c.sacar(30.0);
System.out.println("Saldo: " + c.getSaldo());
try {
c.sacar(1000.0);
} catch (IllegalStateException e) {
System.out.println("Tentativa inválida: " + e.getMessage());
}
}
}
Passo a passo
titularesaldosãoprivate; fora da classe ninguém altera o saldo diretamente.- O construtor valida
titular(não nulo/vazio) esaldoInicial(não negativo) antes de atribuir. depositarrejeita valores<= 0comIllegalArgumentException, pois é um argumento inválido.sacarprimeiro valida o argumento; depois verifica sevalor > saldoe lançaIllegalStateException, porque o problema é o estado atual da conta, não o argumento.- No
main, depositamos 50, sacamos 30 (saldo 120) e tentamos sacar 1000 dentro de umtry/catchpara mostrar a mensagem.
Por que funciona
O invariante "saldo nunca é negativo" é mantido porque toda alteração passa por depositar/sacar, que validam antes de mudar o campo. A distinção entre IllegalArgumentException (entrada ruim) e IllegalStateException (estado impede a operação) deixa o erro mais informativo.
Erros comuns
- Fazer
saldo -= valor;antes de checar:if (valor > saldo) throw ...precisa vir primeiro, senão o saldo pode ficar negativo. - Usar
Exceptiongenérica: dificulta o tratamento específico nocatch. - Permitir
depositar(0): dependendo da regra de negócio, zero não é um depósito válido; aqui rejeitamos com<= 0.
Outra forma de resolver
Você pode centralizar a validação de valores em um método privado:
private static void exigirPositivo(double v) {
if (v <= 0) throw new IllegalArgumentException("valor deve ser positivo");
}
Saída esperada
Saldo: 120.0
Tentativa inválida: saldo insuficiente