Sistema Bancário
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 85 de 87.
Este desafio pede que você construa um Sistema Bancário que modele operações financeiras do mundo real usando princípios de POO.
Seu sistema deve lidar com diferentes tipos de conta, como SavingsAccount e CheckingAccount, ambos estendendo uma classe base Account. Cada tipo de conta tem comportamentos exclusivos: contas de poupança podem render juros, enquanto contas correntes podem ter proteção contra descoberto.
Pense em como modelar transações. Uma interface como Transactable poderia definir métodos para deposit() e withdraw(). Considere usar exceções personalizadas, como InsufficientFundsException, para lidar com operações inválidas de maneira adequada.
Uma classe Bank pode gerenciar várias contas e clientes, demonstrando composição. Você poderia aplicar o padrão Factory para criar diferentes tipos de conta ou usar o padrão Observer para notificar os clientes sobre alterações nas contas.
Concentre-se no encapsulamento para proteger dados confidenciais, como balances e accountNumber, e use polimorfismo para processar diferentes tipos de conta de maneira uniforme.
Desafio
FácilVamos criar um Sistema Bancário completo que demonstra seu domínio dos princípios de POO! Você criará um sistema com diferentes tipos de conta, processamento de transações e gerenciamento adequado de exceções: tudo organizado em vários arquivos.
Você organizará seu código em sete arquivos:
Transactable.java: Crie uma interface que defina o contrato para operações financeiras. Ela deve declarar os métodosdeposit(double amount)ewithdraw(double amount), ambos retornando um booleano para indicar sucesso.InsufficientFundsException.java: Crie uma exceção personalizada que estendaException. O construtor deve aceitar o valor da retirada tentada e o saldo atual, criando uma mensagem no formatoInsufficient funds: attempted [amount], available [balance].Account.java: Crie uma classe base abstrata que represente qualquer conta bancária. Inclua campos privados paraaccountNumber(String) ebalance(double), um construtor que inicialize ambos, getters apropriados, um setter protegido para o saldo (para que as subclasses possam modificá-lo) e um método abstratogetAccountType()que retorne uma String. Implemente um métodogetDetails()que retorne"[accountNumber] ([accountType]): $[balance]", com o saldo formatado para 2 casas decimais.SavingsAccount.java: Crie uma classe que estendaAccounte implementeTransactable. Adicione um campo privado parainterestRate(double). O construtor recebe accountNumber, saldo inicial e interestRate. ImplementegetAccountType()para retornar"Savings". Paradeposit(), adicione o valor ao saldo e retorne true. Parawithdraw(), se o valor exceder o saldo, retorne false; caso contrário, subtraia o valor e retorne true. Adicione um métodoapplyInterest()que aumente o saldo embalance * interestRate(a taxa é armazenada como uma fração, portanto0.05significa 5%).CheckingAccount.java: Crie uma classe que estendaAccounte implementeTransactable. Adicione um campo privado paraoverdraftLimit(double). O construtor recebe accountNumber, saldo inicial e overdraftLimit. ImplementegetAccountType()para retornar"Checking". Paradeposit(), adicione o valor e retorne true. Parawithdraw(), permita a retirada se o valor for menor ou igual ao saldo mais overdraftLimit; retorne false se ele exceder esse limite.Bank.java: Crie uma classe que gerencie contas usando um ArrayList. Inclua os métodos:addAccount(Account account)- adiciona uma conta ao bancofindAccount(String accountNumber)- retorna a Account ou null se não for encontradatransfer(String fromAccount, String toAccount, double amount)- transfere dinheiro entre contas, lançandoInsufficientFundsExceptionse a conta de origem não tiver fundos suficientes. Em caso de sucesso, retorne"Transferred $[amount] from [fromAccount] to [toAccount]"getTotalDeposits()- retorna a soma de todos os saldos das contas
Main.java: Crie seu sistema bancário! Você receberá uma string de comandos separados por vírgulas:SAVINGS:accountNumber:balance:interestRateCHECKING:accountNumber:balance:overdraftLimitDEPOSIT:accountNumber:amountWITHDRAW:accountNumber:amountTRANSFER:fromAccount:toAccount:amountINTEREST:accountNumber
Processe cada comando e imprima:
- SAVINGS/CHECKING:
Account created: [accountNumber] - DEPOSIT:
Deposited $[amount] to [accountNumber] - WITHDRAW:
Withdrew $[amount] from [accountNumber]em caso de sucesso, ouWithdrawal failed: [accountNumber] - TRANSFER: Imprima a mensagem de sucesso ou
Transfer failed: [exception message] - INTEREST:
Interest applied to [accountNumber]
Após todos os comandos, imprima
--- Bank Summary ---, seguido pelos detalhes de cada conta (usandogetDetails()) e, por fim,Total deposits: $[total]formatado para 2 casas decimais.
Você receberá uma entrada: a string de comandos separados por vírgulas.
Por exemplo, com a entrada SAVINGS:SAV001:1000.00:0.05,CHECKING:CHK001:500.00:200.00,DEPOSIT:SAV001:250.00,WITHDRAW:CHK001:600.00,TRANSFER:SAV001:CHK001:100.00,INTEREST:SAV001, sua saída seria:
Account created: SAV001
Account created: CHK001
Deposited $250.00 to SAV001
Withdrew $600.00 from CHK001
Transferred $100.00 from SAV001 to CHK001
Interest applied to SAV001
--- Bank Summary ---
SAV001 (Savings): $1207.50
CHK001 (Checking): $0.00
Total deposits: $1207.50Observe como a conta corrente permite a retirada de $600 apesar de ter apenas $500 de saldo: essa é a proteção contra descoberto em ação! A conta poupança rende 5% de juros sobre seu saldo após a transferência. Este desafio combina herança, interfaces, polimorfismo, exceções personalizadas e encapsulamento em uma aplicação bancária realista!
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// TODO: Crie uma instância de Bank
// TODO: Divida a entrada por vírgula para obter os comandos individuais
// TODO: Processe cada comando:
// - SAVINGS:accountNumber:balance:interestRate -> Create SavingsAccount, print "Account created: [accountNumber]"
// - CHECKING:accountNumber:balance:overdraftLimit -> Create CheckingAccount, print "Account created: [accountNumber]"
// - DEPOSIT:accountNumber:amount -> Deposite e imprima "Deposited $[amount] to [accountNumber]"
// - WITHDRAW:accountNumber:amount -> Withdraw and print success or "Withdrawal failed: [accountNumber]"
// - TRANSFER:fromAccount:toAccount:amount -> Transfira e imprima sucesso ou "Transfer failed: [exception message]"
// - INTEREST:accountNumber -> Apply interest and print "Interest applied to [accountNumber]"
// TODO: Após todos os comandos, imprima "--- Bank Summary ---"
// TODO: Imprima os detalhes de cada conta usando getDetails()
// TODO: Print "Total deposits: $[total]" formatted to 2 decimal places
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy14Desafios Finais
Plataforma de E-LearningSistema BancárioDesenvolvimento de Personagens de JogosServiço de Aluguel de Veículos3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão IteratorPratique por conta própria: Compilador de Java online