Bankensystem
Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 63 von 65.
Aufgabe
SchwerErstelle eine Bank mit zwei Arten von Konten. Jeder Vorgang gibt ein Ergebnis-Dictionary {"ok": bool, "message": String} zurück; der bereitgestellte Code gibt es als OK: MESSAGE oder Failed: MESSAGE aus. Alle Beträge sind float, und jeder Betrag in einer Nachricht hat nach einem $ zwei Dezimalstellen.
Transaction in transaction.gd: Der Konstruktor nimmt kind ("deposit", "withdrawal" oder "interest") und amount entgegen. _to_string() gibt die Art mit einem großgeschriebenen Anfangsbuchstaben und anschließend den Betrag zurück: Deposit - $200.00. Eine Transaktion speichert ihr Konto nicht.
Account in account.gd ist eine @abstract-Klasse:
- Der Konstruktor nimmt
account_number,owner_nameundinitial_balanceentgegen. Das Geld befindet sich in_balance;balanceist eine schreibgeschützte Eigenschaft, deren Getter_balancezurückgibt._historyist einArray[Transaction], undget_history()gibt es zurück. - Zwei abstrakte Methoden:
account_type() -> Stringundwithdrawal_error(amount: float) -> String, die den Grund für die Ablehnung einer Abhebung oder""zurückgibt. deposit(amount): Ein Betrag von0oder weniger schlägt mitDeposit amount must be positivefehl. Andernfalls fügt die Methode das Geld hinzu, protokolliert einedeposit-Transaktion und gibtDeposited $A. New balance: $Bzurück.withdraw(amount): Ein Betrag von0oder weniger schlägt mitWithdrawal amount must be positivefehl; ein nicht leeres Ergebnis vonwithdrawal_error()führt dazu, dass die Methode mit diesem Text fehlschlägt. Andernfalls hebt sie das Geld ab, protokolliert einewithdrawal-Transaktion und gibtWithdrew $A. New balance: $Bzurück, gefolgt von(Overdraft), wenn der Kontostand nun unter0liegt._to_string()gibtTYPE NUMBER (OWNER): $BALANCEzurück.
SavingsAccount in savings_account.gd erweitert Account und hat die Konstanten INTEREST_RATE = 0.02 und MIN_BALANCE = 100.0. Der Kontotyp ist Savings. Eine Abhebung, durch die der Kontostand unter MIN_BALANCE sinken würde, wird mit Cannot withdraw below minimum balance of $100.00 abgelehnt. apply_interest() addiert balance * INTEREST_RATE, protokolliert eine interest-Transaktion und gibt Applied interest: $I. New balance: $B zurück.
CheckingAccount in checking_account.gd erweitert Account und hat die Konstante OVERDRAFT_LIMIT = 200.0. Der Kontotyp ist Checking. Der Kontostand darf bis auf -200.00 sinken; eine Abhebung, durch die er weiter sinken würde, wird mit Cannot exceed overdraft limit of $200.00 abgelehnt.
Bank in bank.gd speichert die Konten in einem privaten Dictionary, dessen Schlüssel die Kontonummern sind:
- Der Konstruktor nimmt
bank_nameentgegen. create_account(kind, account_number, owner_name, initial_balance)ist eine Factory: Beikindwird unabhängig von Groß- und Kleinschreibungsavingsodercheckingangegeben. Der Aufruf schlägt mitAccount number already existsoderInvalid account typefehl und gibt andernfallsSavings account created successfully(oderChecking) zurück.get_account(account_number) -> Accountgibt das Konto odernullzurück.transfer(from_number, to_number, amount): Der Aufruf schlägt mitOne or both accounts not foundfehl; er hebt Geld vom ersten Konto ab und schlägt bei einem Fehlschlag mitTransfer failed:gefolgt von der Nachricht der Abhebung fehl. Andernfalls zahlt er den Betrag auf das zweite Konto ein und gibtTransferred $A from FROM to TOzurück.total_holdings() -> floatgibt die Summe aller Kontostände zurück.
Der bereitgestellte Code liest den Banknamen und anschließend die Befehle ein. Bei folgender Eingabe:
First Bank
open savings|S1|Alice|1000
open checking|C1|Bob|50
withdraw S1|950
transfer S1|C1|300
withdraw C1|400
history C1
totallautet die Ausgabe:
OK: Savings account created successfully
OK: Checking account created successfully
Failed: Cannot withdraw below minimum balance of $100.00
OK: Transferred $300.00 from S1 to C1
OK: Withdrew $400.00. New balance: $-50.00 (Overdraft)
History of C1:
1. Deposit - $300.00
2. Withdrawal - $400.00
Total held by First Bank: $650.00Dein Code gehört in transaction.gd, account.gd, savings_account.gd, checking_account.gd und bank.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
extends Node
func _ready():
# Vorgegebener Eingabe-/Ausgabecode: unverändert lassen
var bank := Bank.new(OS.read_string_from_stdin())
var line := OS.read_string_from_stdin()
while line != "":
var parts := line.split(" ", true, 1)
var f: PackedStringArray = parts[1].split("|") if parts.size() > 1 else PackedStringArray()
match parts[0]:
"open":
show_result(bank.create_account(f[0], f[1], f[2], float(f[3])))
"deposit":
show_result(bank.get_account(f[0]).deposit(float(f[1])))
"withdraw":
show_result(bank.get_account(f[0]).withdraw(float(f[1])))
"interest":
var account: Account = bank.get_account(f[0])
if account is SavingsAccount:
var savings := account as SavingsAccount
show_result(savings.apply_interest())
else:
print("Failed: ", f[0], " is not a savings account")
"transfer":
show_result(bank.transfer(f[0], f[1], float(f[2])))
"history":
var history: Array = bank.get_account(f[0]).get_history()
print("History of ", f[0], ":")
for i in history.size():
print(i + 1, ". ", history[i])
"account":
print(bank.get_account(f[0]))
"total":
print("Total held by %s: $%.2f" % [bank.bank_name, bank.total_holdings()])
line = OS.read_string_from_stdin()
func show_result(result: Dictionary) -> void:
print(("OK: " if result["ok"] else "Failed: ") + result["message"])
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort selfMethodenEigenschaftenKonstruktor (_init)Wiederholung – Einfacher Taschenrechner4Polymorphie
Methodenüberschreibung erneut betrachtetDuck-TypisierungAbstrakte Klassen und MethodenSchnittstellendesignRückblick – Formrechner2Klassenattribute
Instanz- vs. statische VariablenStatische FunktionenProperty-SetterProperty-GetterPrivat nach KonventionWiederholung – Bankkontenverwaltung5Kapselung
Öffentliche und private MemberValidierung mit SetternInformationsverbergenSchreibgeschützte EigenschaftenRückblick – System zur Schülerverwaltung8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungInnere KlassenNodes als KomponentenRefCounted vs. NodeEnums in Klassen11Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungVererbungskettenTypprüfungen mit isWiederholung – Mitarbeiterhierarchie6Spezielle Methoden
Einführung in virtuelle MethodenDie _to_string-MethodeBenutzerdefinierte IteratorenRückblick – Benutzerdefinierte Liste9Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBeobachter-MusterStrategie-Muster12Abschließende Herausforderungen
E-Learning-PlattformBankensystemEntwicklung von SpielfigurenFahrzeugvermietungÜbe selbstständig: Online-GDScript-Compiler