Menu
Coddy logo textTech

Banksystem

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 85 von 87.

Diese Challenge stellt Ihnen die Aufgabe, ein Bankensystem zu entwickeln, das reale Finanzvorgänge mithilfe von OOP-Prinzipien modelliert.

Ihr System sollte verschiedene Kontotypen wie SavingsAccount und CheckingAccount verarbeiten, die beide eine Basisklasse Account erweitern. Jeder Kontotyp hat ein einzigartiges Verhalten: Sparkonten könnten Zinsen einbringen, während Girokonten einen Überziehungsschutz haben könnten.

Überlegen Sie, wie Sie Transaktionen modellieren können. Ein Interface wie Transactable könnte Methoden für deposit() und withdraw() definieren. Erwägen Sie die Verwendung benutzerdefinierter Exceptions wie InsufficientFundsException, um ungültige Operationen elegant zu handhaben.

Eine Bank-Klasse könnte mehrere Konten und Kunden verwalten und so Komposition demonstrieren. Sie könnten das Factory-Muster anwenden, um verschiedene Kontotypen zu erstellen, oder das Observer-Muster verwenden, um Kunden über Kontoänderungen zu benachrichtigen.

Konzentrieren Sie sich auf Kapselung, um sensible Daten wie Kontostände und Kontonummern zu schützen, und nutzen Sie Polymorphismus, um verschiedene Kontotypen einheitlich zu verarbeiten.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein komplettes Bankensystem bauen, das Ihre Beherrschung der OOP-Prinzipien demonstriert! Sie erstellen ein System mit verschiedenen Kontotypen, Transaktionsabwicklung und ordnungsgemäßem Exception-Management – alles organisiert über mehrere Dateien hinweg.

Sie werden Ihren Code in sieben Dateien organisieren:

  • Transactable.java: Erstellen Sie ein Interface, das den Vertrag für Finanzoperationen definiert. Es sollte die Methoden deposit(double amount) und withdraw(double amount) deklarieren, die beide einen Boolean zurückgeben, um den Erfolg anzuzeigen.
  • InsufficientFundsException.java: Erstellen Sie eine benutzerdefinierte Exception, die Exception erweitert. Der Konstruktor sollte den versuchten Auszahlungsbetrag und den aktuellen Kontostand akzeptieren und eine Nachricht im Format Insufficient funds: attempted [amount], available [balance] erstellen.
  • Account.java: Erstellen Sie eine abstrakte Basisklasse, die ein beliebiges Bankkonto repräsentiert. Fügen Sie private Felder für accountNumber (String) und balance (double) hinzu, einen Konstruktor, der beide initialisiert, entsprechende Getter, einen geschützten Setter für balance (damit Unterklassen ihn ändern können) und eine abstrakte Methode getAccountType(), die einen String zurückgibt. Implementieren Sie eine getDetails()-Methode, die "[accountNumber] ([accountType]): $[balance]" zurückgibt, wobei der Kontostand auf 2 Dezimalstellen formatiert ist.
  • SavingsAccount.java: Erstellen Sie eine Klasse, die Account erweitert und Transactable implementiert. Fügen Sie ein privates Feld für interestRate (double) hinzu. Der Konstruktor nimmt accountNumber, initial balance und interestRate entgegen. Implementieren Sie getAccountType() so, dass "Savings" zurückgegeben wird. Für deposit() addieren Sie den Betrag zum Kontostand und geben true zurück. Für withdraw() geben Sie false zurück, wenn der Betrag den Kontostand übersteigt; andernfalls subtrahieren Sie ihn und geben true zurück. Fügen Sie eine Methode applyInterest() hinzu, die den Kontostand um den Prozentsatz des Zinssatzes erhöht.
  • CheckingAccount.java: Erstellen Sie eine Klasse, die Account erweitert und Transactable implementiert. Fügen Sie ein privates Feld für overdraftLimit (double) hinzu. Der Konstruktor nimmt accountNumber, initial balance und overdraftLimit entgegen. Implementieren Sie getAccountType() so, dass "Checking" zurückgegeben wird. Für deposit() addieren Sie den Betrag und geben true zurück. Für withdraw() erlauben Sie die Auszahlung, wenn der Betrag kleiner oder gleich dem Kontostand plus overdraftLimit ist; geben Sie false zurück, wenn er dieses Limit überschreitet.
  • Bank.java: Erstellen Sie eine Klasse, die Konten mithilfe einer ArrayList verwaltet. Fügen Sie folgende Methoden hinzu:
    • addAccount(Account account) – fügt ein Konto zur Bank hinzu
    • findAccount(String accountNumber) – gibt das Account-Objekt zurück oder null, falls nicht gefunden
    • transfer(String fromAccount, String toAccount, double amount) – überträgt Geld zwischen Konten und wirft eine InsufficientFundsException, wenn das Quellkonto nicht genügend Deckung hat. Geben Sie bei Erfolg "Transferred $[amount] from [fromAccount] to [toAccount]" zurück
    • getTotalDeposits() – gibt die Summe aller Kontostände zurück
  • Main.java: Bauen Sie Ihr Bankensystem! Sie erhalten einen kommagetrennten String mit Befehlen:
    • SAVINGS:accountNumber:balance:interestRate
    • CHECKING:accountNumber:balance:overdraftLimit
    • DEPOSIT:accountNumber:amount
    • WITHDRAW:accountNumber:amount
    • TRANSFER:fromAccount:toAccount:amount
    • INTEREST:accountNumber

    Verarbeiten Sie jeden Befehl und geben Sie Folgendes aus:

    • SAVINGS/CHECKING: Account created: [accountNumber]
    • DEPOSIT: Deposited $[amount] to [accountNumber]
    • WITHDRAW: Withdrew $[amount] from [accountNumber] bei Erfolg, oder Withdrawal failed: [accountNumber]
    • TRANSFER: Geben Sie die Erfolgsmeldung oder Transfer failed: [exception message] aus
    • INTEREST: Interest applied to [accountNumber]

    Geben Sie nach allen Befehlen --- Bank Summary --- aus, gefolgt von den Details jedes Kontos (unter Verwendung von getDetails()) und schließlich Total deposits: $[total], formatiert auf 2 Dezimalstellen.

Sie erhalten eine Eingabe: den kommagetrennten Befehls-String.

Zum Beispiel bei der Eingabe 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 wäre Ihre Ausgabe:

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

Beachten Sie, wie das Girokonto die Auszahlung von $600 ermöglicht, obwohl es nur $500 Guthaben hat – das ist der Überziehungsschutz in Aktion! Das Sparkonto erhält nach dem Transfer 5% Zinsen auf seinen Kontostand. Diese Herausforderung kombiniert Vererbung, Interfaces, Polymorphismus, benutzerdefinierte Exceptions und Kapselung in einer realistischen Bankanwendung!

Spickzettel

Ein Bankensystem demonstriert OOP-Prinzipien durch Kontoverwaltung, Transaktionen und Ausnahmebehandlung.

Interfaces für Verträge

Definieren Sie gemeinsame Operationen mithilfe von Interfaces:

public interface Transactable {
    boolean deposit(double amount);
    boolean withdraw(double amount);
}

Benutzerdefinierte Ausnahmen

Erstellen Sie benutzerdefinierte Ausnahmen für domänenspezifische Fehler:

public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(double attempted, double available) {
        super("Insufficient funds: attempted " + attempted + ", available " + available);
    }
}

Abstrakte Basisklassen

Verwenden Sie abstrakte Klassen, um eine gemeinsame Struktur mit abstrakten Methoden für subklassenspezifisches Verhalten zu definieren:

public abstract class Account {
    private String accountNumber;
    private double balance;
    
    public abstract String getAccountType();
    
    protected void setBalance(double balance) {
        this.balance = balance;
    }
}

Vererbung und Polymorphismus

Subklassen erweitern Basisklassen und implementieren Interfaces:

public class SavingsAccount extends Account implements Transactable {
    private double interestRate;
    
    @Override
    public String getAccountType() {
        return "Savings";
    }
    
    public void applyInterest() {
        setBalance(getBalance() * (1 + interestRate));
    }
}

Komposition

Klassen können Sammlungen anderer Objekte verwalten:

public class Bank {
    private ArrayList<Account> accounts;
    
    public void addAccount(Account account) {
        accounts.add(account);
    }
    
    public Account findAccount(String accountNumber) {
        // Suche und Rückgabe des Kontos oder null
    }
}

Kapselung

Schützen Sie sensible Daten mit privaten Feldern und kontrolliertem Zugriff über Getter/Setter. Verwenden Sie protected-Modifikatoren, um den Zugriff auf Subklassen zu ermöglichen und gleichzeitig die Kapselung beizubehalten.

Ausnahmebehandlung in Transaktionen

Werfen Sie benutzerdefinierte Ausnahmen für ungültige Operationen:

public String transfer(String from, String to, double amount) throws InsufficientFundsException {
    if (!fromAccount.withdraw(amount)) {
        throw new InsufficientFundsException(amount, fromAccount.getBalance());
    }
    toAccount.deposit(amount);
    return "Transferred $" + amount;
}

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: Erstelle eine Bank-Instanz
        
        // TODO: Teile die Eingabe durch Kommas, um einzelne Befehle zu erhalten
        
        // TODO: Verarbeite jeden Befehl:
        // - SAVINGS:accountNumber:balance:interestRate -> Erstelle SavingsAccount, gib "Account created: [accountNumber]" aus
        // - CHECKING:accountNumber:balance:overdraftLimit -> Erstelle CheckingAccount, gib "Account created: [accountNumber]" aus
        // - DEPOSIT:accountNumber:amount -> Zahle ein und gib "Deposited $[amount] to [accountNumber]" aus
        // - WITHDRAW:accountNumber:amount -> Hebe ab und gib Erfolg oder "Withdrawal failed: [accountNumber]" aus
        // - TRANSFER:fromAccount:toAccount:amount -> Überweise und gib Erfolg oder "Transfer failed: [exception message]" aus
        // - INTEREST:accountNumber -> Wende Zinsen an und gib "Interest applied to [accountNumber]" aus
        
        // TODO: Gib nach allen Befehlen "--- Bank Summary ---" aus
        
        // TODO: Gib die Details jedes Kontos mit getDetails() aus
        
        // TODO: Gib "Total deposits: $[total]" auf 2 Dezimalstellen formatiert aus
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung