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.
Aufgabe
EinfachLassen 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 Methodendeposit(double amount)undwithdraw(double amount)deklarieren, die beide einen Boolean zurückgeben, um den Erfolg anzuzeigen.InsufficientFundsException.java: Erstellen Sie eine benutzerdefinierte Exception, dieExceptionerweitert. Der Konstruktor sollte den versuchten Auszahlungsbetrag und den aktuellen Kontostand akzeptieren und eine Nachricht im FormatInsufficient 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üraccountNumber(String) undbalance(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 MethodegetAccountType(), die einen String zurückgibt. Implementieren Sie einegetDetails()-Methode, die"[accountNumber] ([accountType]): $[balance]"zurückgibt, wobei der Kontostand auf 2 Dezimalstellen formatiert ist.SavingsAccount.java: Erstellen Sie eine Klasse, dieAccounterweitert undTransactableimplementiert. Fügen Sie ein privates Feld fürinterestRate(double) hinzu. Der Konstruktor nimmt accountNumber, initial balance und interestRate entgegen. Implementieren SiegetAccountType()so, dass"Savings"zurückgegeben wird. Fürdeposit()addieren Sie den Betrag zum Kontostand und geben true zurück. Fürwithdraw()geben Sie false zurück, wenn der Betrag den Kontostand übersteigt; andernfalls subtrahieren Sie ihn und geben true zurück. Fügen Sie eine MethodeapplyInterest()hinzu, die den Kontostand um den Prozentsatz des Zinssatzes erhöht.CheckingAccount.java: Erstellen Sie eine Klasse, dieAccounterweitert undTransactableimplementiert. Fügen Sie ein privates Feld füroverdraftLimit(double) hinzu. Der Konstruktor nimmt accountNumber, initial balance und overdraftLimit entgegen. Implementieren SiegetAccountType()so, dass"Checking"zurückgegeben wird. Fürdeposit()addieren Sie den Betrag und geben true zurück. Fürwithdraw()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 hinzufindAccount(String accountNumber)– gibt das Account-Objekt zurück oder null, falls nicht gefundentransfer(String fromAccount, String toAccount, double amount)– überträgt Geld zwischen Konten und wirft eineInsufficientFundsException, wenn das Quellkonto nicht genügend Deckung hat. Geben Sie bei Erfolg"Transferred $[amount] from [fromAccount] to [toAccount]"zurückgetTotalDeposits()– gibt die Summe aller Kontostände zurück
Main.java: Bauen Sie Ihr Bankensystem! Sie erhalten einen kommagetrennten String mit Befehlen:SAVINGS:accountNumber:balance:interestRateCHECKING:accountNumber:balance:overdraftLimitDEPOSIT:accountNumber:amountWITHDRAW:accountNumber:amountTRANSFER:fromAccount:toAccount:amountINTEREST: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, oderWithdrawal 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 vongetDetails()) und schließlichTotal 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.50Beachten 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
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas this-SchlüsselwortMethodenFelder (Attribute)Konstruktor-MethodeKonstruktor-ÜberladungRückblick – Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (extends)Das super-SchlüsselwortMethoden überschreiben (@Override)Konstruktor-VerkettungDie Object-KlasseEinfache & mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenZusammenfassung - Mitarbeiter-Hierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-InterfaceZusammenfassung – Benutzerdefiniertes Sortieren2Zugriffsmodifikatoren & Kapselung
Überblick über ZugriffsebenenGetter- und Setter-MethodenInformation HidingDas final-SchlüsselwortRückblick – Bankkonto-Manager5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenZusammenfassung – Formenrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, geschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Sealed Classes (Java 17+)11Design Patterns Teil 1
Einführung in Design PatternsSingleton-PatternFactory-PatternBuilder-PatternObserver-PatternStrategy-Pattern14Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung3Klasseneigenschaften & Statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Zusammenfassung – Zähler & Utility6Interfaces & Abstrakte Klassen
Einführung in InterfacesInterfaces implementierenImplementierung mehrerer InterfacesDefault- & statische Methoden in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesZusammenfassung - Zahlungssystem