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 unter Verwendung von OOP-Prinzipien modelliert.

Ihr System sollte verschiedene Kontotypen wie SavingsAccount und CheckingAccount handhaben, die beide eine Basisklasse Account erweitern. Jeder Kontotyp hat einzigartige Verhaltensweisen: 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 die 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 Ausnahme-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 beides initialisiert, entsprechende Getter, einen geschützten Setter für den Kontostand (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 übernimmt accountNumber, initial balance und interestRate. Implementieren Sie getAccountType() so, dass "Savings" zurückgegeben wird. Addieren Sie für deposit() den Betrag zum Kontostand und geben Sie true zurück. Wenn bei withdraw() der Betrag den Kontostand übersteigt, geben Sie false zurück; andernfalls subtrahieren Sie ihn und geben Sie true zurück. Fügen Sie eine Methode applyInterest() hinzu, die den Kontostand um balance * interestRate erhöht (der Zinssatz wird als Bruchteil gespeichert, also bedeutet 0.05 5%).
  • 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 übernimmt accountNumber, initial balance und overdraftLimit. Implementieren Sie getAccountType() so, dass "Checking" zurückgegeben wird. Addieren Sie für deposit() den Betrag und geben Sie true zurück. Erlauben Sie bei withdraw() 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 der Bank ein Konto hinzu
    • findAccount(String accountNumber) – gibt das Account-Objekt oder null zurück, falls es nicht gefunden wurde
    • 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 wäre 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 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 ein Guthaben von $500 hat – das ist der Überziehungsschutz in Aktion! Das Sparkonto erhält 5% Zinsen auf seinen Kontostand nach der Überweisung. Diese Herausforderung kombiniert Vererbung, Interfaces, Polymorphismus, benutzerdefinierte Exceptions und Kapselung in einer realistischen Bankanwendung!

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