Menu
Coddy logo textTech

Sistema bancario

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 85 de 87.

Este desafío te propone construir un sistema bancario que modele operaciones financieras del mundo real utilizando principios de POO.

Tu sistema debería gestionar distintos tipos de cuenta como SavingsAccount y CheckingAccount, ambos extendiendo una clase base Account. Cada tipo de cuenta tiene comportamientos únicos: las cuentas de ahorro podrían generar intereses, mientras que las cuentas corrientes podrían tener protección contra sobregiros.

Piensa en cómo modelar las transacciones. Una interfaz como Transactable podría definir métodos para deposit() y withdraw(). Considera usar excepciones personalizadas como InsufficientFundsException para gestionar las operaciones no válidas correctamente.

Una clase Bank podría gestionar varias cuentas y clientes, demostrando la composición. Podrías aplicar el patrón Factory para crear diferentes tipos de cuenta o usar el patrón Observer para notificar a los clientes sobre los cambios en las cuentas.

Concéntrate en la encapsulación para proteger datos confidenciales como los saldos y los números de cuenta, y usa el polimorfismo para procesar de manera uniforme diferentes tipos de cuenta.

challenge icon

Desafío

Fácil

¡Construyamos un Sistema Bancario completo que demuestre tu dominio de los principios de OOP! Crearás un sistema con diferentes tipos de cuentas, gestión de transacciones y una gestión adecuada de excepciones: todo organizado en varios archivos.

Organizarás tu código en siete archivos:

  • Transactable.java: Crea una interfaz que defina el contrato para las operaciones financieras. Debe declarar los métodos deposit(double amount) y withdraw(double amount), ambos devolviendo un booleano para indicar si la operación tuvo éxito.
  • InsufficientFundsException.java: Crea una excepción personalizada que extienda Exception. El constructor debe aceptar el importe del retiro intentado y el saldo actual, creando un mensaje con el formato Insufficient funds: attempted [amount], available [balance].
  • Account.java: Crea una clase base abstracta que represente cualquier cuenta bancaria. Incluye campos privados para accountNumber (String) y balance (double), un constructor que inicialice ambos, getters apropiados, un setter protegido para balance (para que las subclases puedan modificarlo) y un método abstracto getAccountType() que devuelva un String. Implementa un método getDetails() que devuelva "[accountNumber] ([accountType]): $[balance]" con el balance formateado con 2 decimales.
  • SavingsAccount.java: Crea una clase que extienda Account e implemente Transactable. Añade un campo privado para interestRate (double). El constructor recibe accountNumber, balance inicial e interestRate. Implementa getAccountType() para que devuelva "Savings". Para deposit(), suma el importe al balance y devuelve true. Para withdraw(), si el importe supera el balance, devuelve false; de lo contrario, resta el importe y devuelve true. Añade un método applyInterest() que incremente el balance en balance * interestRate (la tasa se almacena como una fracción, por lo que 0.05 significa 5%).
  • CheckingAccount.java: Crea una clase que extienda Account e implemente Transactable. Añade un campo privado para overdraftLimit (double). El constructor recibe accountNumber, balance inicial y overdraftLimit. Implementa getAccountType() para que devuelva "Checking". Para deposit(), suma el importe y devuelve true. Para withdraw(), permite el retiro si el importe es menor o igual que el balance más overdraftLimit; devuelve false si supera este límite.
  • Bank.java: Crea una clase que gestione las cuentas mediante un ArrayList. Incluye los métodos:
    • addAccount(Account account) - añade una cuenta al banco
    • findAccount(String accountNumber) - devuelve la Account o null si no se encuentra
    • transfer(String fromAccount, String toAccount, double amount) - transfiere dinero entre cuentas y lanza InsufficientFundsException si la cuenta de origen no tiene fondos suficientes. Si tiene éxito, devuelve "Transferred $[amount] from [fromAccount] to [toAccount]"
    • getTotalDeposits() - devuelve la suma de los balances de todas las cuentas
  • Main.java: ¡Construye tu sistema bancario! Recibirás una cadena de comandos separados por comas:
    • SAVINGS:accountNumber:balance:interestRate
    • CHECKING:accountNumber:balance:overdraftLimit
    • DEPOSIT:accountNumber:amount
    • WITHDRAW:accountNumber:amount
    • TRANSFER:fromAccount:toAccount:amount
    • INTEREST:accountNumber

    Procesa cada comando e imprime:

    • SAVINGS/CHECKING: Account created: [accountNumber]
    • DEPOSIT: Deposited $[amount] to [accountNumber]
    • WITHDRAW: Withdrew $[amount] from [accountNumber] si tiene éxito, o Withdrawal failed: [accountNumber]
    • TRANSFER: imprime el mensaje de éxito o Transfer failed: [exception message]
    • INTEREST: Interest applied to [accountNumber]

    Después de todos los comandos, imprime --- Bank Summary ---, seguido de los detalles de cada cuenta (usando getDetails()) y, finalmente, Total deposits: $[total] formateado con 2 decimales.

Recibirás una entrada: la cadena de comandos separados por comas.

Por ejemplo, con la 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, tu salida sería:

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.50

Observa cómo la cuenta corriente permite retirar $600 a pesar de tener solo un balance de $500: ¡esa es la protección contra sobregiros en acción! La cuenta de ahorros obtiene un 5% de interés sobre su balance después de la transferencia. ¡Este desafío combina herencia, interfaces, polimorfismo, excepciones personalizadas y encapsulación en una aplicación bancaria realista!

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: Crea una instancia de Bank
        
        // TODO: Separa la entrada por comas para obtener los comandos individuales
        
        // TODO: Procesa 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 -> Deposita e imprime "Deposited $[amount] to [accountNumber]"
        // - WITHDRAW:accountNumber:amount -> Withdraw and print success or "Withdrawal failed: [accountNumber]"
        // - TRANSFER:fromAccount:toAccount:amount -> Transfiere e imprime éxito o "Transfer failed: [exception message]"
        // - INTEREST:accountNumber -> Apply interest and print "Interest applied to [accountNumber]"
        
        // TODO: Después de todos los comandos, imprime "--- Bank Summary ---"
        
        // TODO: Imprime los detalles de cada cuenta usando getDetails()
        
        // TODO: Print "Total deposits: $[total]" formatted to 2 decimal places
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online