Bankingsystem
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 108 von 110.
Aufgabe
EinfachErstellen wir ein Bankensystem, das reale Finanzoperationen mithilfe der OOP-Prinzipien modelliert, die du im Laufe dieses Kurses gemeistert hast. Du wirst Konten mit unterschiedlichen Regeln erstellen, Transaktionen verfolgen und Kunden verwalten – alles organisiert über mehrere Dateien.
Dein Bankensystem wird auf sechs Dateien verteilt:
transaction.dart: Erstelle eineTransaction-Klasse, die einen unveränderlichen Datensatz einer Finanzoperation darstellt. Jede Transaktion besitztfinal-Felder fürtype(String – "deposit", "withdrawal" oder "transfer"),amount(double) undtimestamp(DateTime). ÜberschreibetoString(), sodass[type] $amountzurückgegeben wird.account.dart: Erstelle eine abstrakteAccount-Klasse mit einem privaten_balance(double), einerfinal-Kontonummer (accountNumber– String) und einerList<Transaction>zum Speichern des Transaktionsverlaufs. Füge einen Getter für den Kontostand, einen geschützten Setterset balance(double value)hinzu, damit Unterklassen in anderen Dateien den Kontostand aktualisieren können, sowie eine abstrakte Methodebool canWithdraw(double amount), die von Unterklassen implementiert wird, und diese konkreten Methoden:deposit(double amount)– addiert den Betrag zum Kontostand, zeichnet eine Transaktion auf und gibtDeposited $amount. Balance: $balanceauswithdraw(double amount)– wenncanWithdraw()true zurückgibt, wird der Betrag vom Kontostand abgezogen, eine Transaktion aufgezeichnet undWithdrew $amount. Balance: $balanceausgegeben. Andernfalls wirdWithdrawal deniedausgegeben.getTransactionCount()– gibt die Anzahl der Transaktionen zurück
savings_account.dart: Erstelle einSavingsAccount, dasAccounterweitert. Sparkonten haben ein Auszahlungslimit – sie können in einer einzelnen Transaktion nicht mehr als 500 $ abheben. ImplementierecanWithdraw(), um diese Regel durchzusetzen (stelle außerdem sicher, dass der Kontostand ausreicht). Füge eine MethodeapplyInterest(double rate)hinzu, die den Kontostand mithilfe desbalance-Getters und -Setters um den angegebenen Prozentsatz erhöht und anschließendInterest applied. Balance: $balanceausgibt.checking_account.dart: Erstelle einCheckingAccount, dasAccounterweitert. Girokonten verfügen über einen Überziehungsschutz bis zu 100 $ – sie können ins Minus gehen, aber nicht unter -100 $. ImplementierecanWithdraw(), sodass Auszahlungen erlaubt werden, solange der resultierende Kontostand mindestens -100 $ beträgt.customer.dart: Erstelle eineCustomer-Klasse mit einerid(String), einemname(String) und einerList<Account>für die Konten des Kunden. Füge die MethodeaddAccount(Account account)zum Hinzufügen eines Kontos sowiegetTotalBalance()hinzu, die die Summe aller Kontostände zurückgibt. ÜberschreibetoString(), sodassCustomer: name (X accounts)zurückgegeben wird.main.dart: Veranschauliche dein Bankensystem. Erstelle einen Kunden (C001,John Smith). Erstelle einSavingsAccount(SAV001, Anfangssaldo 1000 $) und einCheckingAccount(CHK001, Anfangssaldo 500 $). Füge beide Konten dem Kunden hinzu und gib den Kunden aus. Führe anschließend diese Operationen aus:- Zahle 200 $ auf das Sparkonto ein
- Hebe 300 $ vom Sparkonto ab (sollte erfolgreich sein)
- Versuche, 600 $ vom Sparkonto abzuheben (sollte abgelehnt werden – überschreitet das Limit)
- Wende 5 % Zinsen auf das Sparkonto an
- Hebe 550 $ vom Girokonto ab (sollte mithilfe des Überziehungsschutzes erfolgreich sein)
- Versuche, weitere 100 $ vom Girokonto abzuheben (sollte abgelehnt werden – würde das Überziehungslimit überschreiten)
Savings transactions: XundTotal balance: $Yaus (auf 2 Nachkommastellen formatiert).
Erwartete Ausgabe:
Customer: John Smith (2 accounts)
Deposited $200.0. Balance: $1200.0
Withdrew $300.0. Balance: $900.0
Withdrawal denied
Interest applied. Balance: $945.0
Withdrew $550.0. Balance: $-50.0
Withdrawal denied
Savings transactions: 3
Total balance: $895.00Probier es selbst
import 'transaction.dart';
import 'account.dart';
import 'savings_account.dart';
import 'checking_account.dart';
import 'customer.dart';
void main() {
// TODO: Erstelle einen Kunden mit der id "C001" und dem Namen "John Smith"
// TODO: Erstelle ein SavingsAccount mit der accountNumber "SAV001" und einem Startguthaben von $1000
// TODO: Erstelle ein CheckingAccount mit der accountNumber "CHK001" und einem Startguthaben von $500
// TODO: Füge beide Konten dem Kunden hinzu
// TODO: Gib den Kunden aus
// TODO: Führe die folgenden Operationen aus:
// 1. Zahle $200 auf das Sparkonto ein
// 2. Hebe $300 vom Sparkonto ab (sollte erfolgreich sein)
// 3. Versuche $600 vom Sparkonto abzuheben (sollte abgelehnt werden - überschreitet das Limit)
// 4. Wende 5% Zinsen auf das Sparkonto an
// 5. Hebe $550 vom Girokonto ab (sollte unter Nutzung des Überziehungsrahmens erfolgreich sein)
// 6. Versuche weitere $100 vom Girokonto abzuheben (sollte abgelehnt werden - würde das Überziehungslimit überschreiten)
// TODO: Gib "Savings transactions: X" aus, wobei X die Anzahl der Transaktionen ist
// TODO: Gib "Total balance: \$Y" aus, wobei Y auf 2 Dezimalstellen formatiert ist
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienBibliotheken & ImportsEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort thisMethodenInstanzvariablenGrundlagen von KonstruktorenRückblick – Einfacher Taschenrechner4Null-Sicherheit
Einführung in die Null-SicherheitNullable vs. Non-NullableDie Operatoren ? und !Late-Schlüsselwort und Null-SicherheitNull-bewusste OperatorenNull-Sicherheit in KlassenRückblick – Benutzers профilsystem7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrere InterfacesZusammenfassung – Formrechner10Collections & Generics
Übersicht über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische EinschränkungenIterable & IteratorRückblick – Generischer Speicher13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungErweiterungsmethodenAufrufbare KlassenVersiegelte Klassen (Dart 3)Records (Dart 3)Muster & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
StandardkonstruktorBenannte KonstruktorenInitialisierungslistenKonstantenkonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenRückblick – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _-Präfix-KonventionBibliotheksweite SichtbarkeitTiefergehende Getter & SetterInformationsverbergungRückblick – Studierendendaten8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas Schlüsselwort „on“ in MixinsMixin vs. VererbungMixin vs. SchnittstelleRückblick – Tiersystem11Spezielle Methoden
toString()-ÜberschreibunghashCode- & ==-ÜberschreibungComparable-Schnittstellecall()-MethodenoSuchMethod-ÜberschreibungWiederholung – Benutzerdefinierte Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFabrikmusterBeobachtermusterStrategiemuster17Abschließende Herausforderungen
E-Learning-PlattformBankingsystemSpielcharaktersystemFahrzeugvermietung3Klassen-Eigenschaften
Instanz- vs. statische MemberFinal- und Const-FelderLate-VariablenStatische Methoden und FelderGetter und SetterRückblick – Bankkontoverwaltung6Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungDie Annotation @overrideDas Schlüsselwort final für KlassenKonstruktoren und VererbungZusammenfassung – Mitarbeiterhierarchie9Polymorphismus
Grundlagen des PolymorphismusPolymorphismus über InterfacesLaufzeit-TypüberprüfungDie Operatoren is & asCovariant-SchlüsselwortZusammenfassung – ZahlungsprozessorÜbe selbstständig: Online-Dart-Compiler