Banksystem
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 108 von 110.
Aufgabe
EinfachLassen Sie uns ein Bankensystem bauen, das reale Finanzoperationen unter Verwendung der OOP-Prinzipien modelliert, die Sie in diesem Kurs gemeistert haben. Sie werden Konten mit unterschiedlichen Regeln erstellen, Transaktionen verfolgen und Kunden verwalten – alles organisiert über mehrere Dateien hinweg.
Ihr Bankensystem wird in sechs Dateien organisiert sein:
transaction.dart: Erstellen Sie eineTransaction-Klasse, die einen unveränderlichen Datensatz einer Finanzoperation darstellt. Jede Transaktion hatfinal-Felder fürtype(String - "deposit", "withdrawal" oder "transfer"),amount(double) undtimestamp(DateTime). Überschreiben SietoString(), um[type] $amountzurückzugeben.account.dart: Erstellen Sie eine abstrakteAccount-Klasse mit einem privaten_balance(double), einerfinalKontonummer (accountNumber- String) und einerList<Transaction>, um den Transaktionsverlauf zu speichern. Fügen Sie einen Getter für den Kontostand hinzu, einen geschützten Setterset balance(double value), damit Unterklassen in anderen Dateien den Kontostand aktualisieren können, eine abstrakte Methodebool canWithdraw(double amount), die von Unterklassen implementiert wird, und diese konkreten Methoden:deposit(double amount)- erhöht den Kontostand, zeichnet eine Transaktion auf und gibtDeposited $amount. Balance: $balanceaus.withdraw(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: Erstellen Sie einSavingsAccount, dasAccounterweitert. Sparkonten haben ein Auszahlungslimit – es können nicht mehr als $500 in einer einzelnen Transaktion abgehoben werden. Implementieren SiecanWithdraw(), um diese Regel durchzusetzen (stellen Sie auch ein ausreichendes Guthaben sicher). Fügen Sie eine MethodeapplyInterest(double rate)hinzu, die den Kontostand um den angegebenen Prozentsatz unter Verwendung desbalanceGetters und Setters erhöht und dannInterest applied. Balance: $balanceausgibt.checking_account.dart: Erstellen Sie einCheckingAccount, dasAccounterweitert. Girokonten haben einen Überziehungsschutz bis zu $100 – sie können ins Minus gehen, aber nicht unter -$100. Implementieren SiecanWithdraw(), um Auszahlungen zu ermöglichen, solange der resultierende Kontostand bei oder über -$100 bleibt.customer.dart: Erstellen Sie eineCustomer-Klasse mit einerid(String), einemname(String) und einerList<Account>für deren Konten. Fügen Sie die MethodenaddAccount(Account account)zum Hinzufügen eines Kontos undgetTotalBalance()hinzu, die die Summe aller Kontostände zurückgibt. Überschreiben SietoString(), umCustomer: name (X accounts)zurückzugeben.main.dart: Demonstrieren Sie Ihr Bankensystem. Erstellen Sie einen Kunden (C001,John Smith). Erstellen Sie einSavingsAccount(SAV001, Startguthaben $1000) und einCheckingAccount(CHK001, Startguthaben $500). Fügen Sie beide Konten dem Kunden hinzu und geben Sie den Kunden aus. Führen Sie dann diese Operationen aus:- Zahlen Sie $200 auf das Sparkonto ein
- Heben Sie $300 vom Sparkonto ab (sollte erfolgreich sein)
- Versuchen Sie, $600 vom Sparkonto abzuheben (sollte abgelehnt werden – überschreitet das Limit)
- Wenden Sie 5% Zinsen auf das Sparkonto an
- Heben Sie $550 vom Girokonto ab (sollte unter Nutzung des Überziehungsschutzes erfolgreich sein)
- Versuchen Sie, weitere $100 vom Girokonto abzuheben (sollte abgelehnt werden – würde das Überziehungslimit überschreiten)
Savings transactions: XundTotal balance: $Yaus (formatiert auf 2 Dezimalstellen).
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.0Probier 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 den Überziehungsrahmen ü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 this-SchlüsselwortMethodenInstanzvariablenKonstruktor-GrundlagenWiederholung – Einfacher Taschenrechner4Null-Sicherheit
Einführung in Null-SicherheitNullable vs. Non-NullableDie ? und ! OperatorenLate-Schlüsselwort & Null-SicherheitNull-aware OperatorenNull-Sicherheit in KlassenZusammenfassung – Benutzerprofil-System7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrfache InterfacesRückblick – Shape Calculator10Collections & Generics
Überblick über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische ConstraintsIterable & IteratorZusammenfassung – Generische Speicherung13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
Standard-KonstruktorBenannte KonstruktorenInitialisierungslistenKonstante KonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenZusammenfassung – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _ Präfix-KonventionSichtbarkeit auf Library-EbeneGetter & Setter im DetailInformation HidingRückblick – Schülerdatensätze8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas on-Schlüsselwort in MixinsMixin vs. VererbungMixin vs. InterfaceZusammenfassung - Tiersystem11Spezielle Methoden
toString() überschreibenhashCode & == überschreibenComparable-Interfacecall()-MethodenoSuchMethod überschreibenZusammenfassung – Eigene Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster3Klasseneigenschaften
Instanz- vs. statische MemberFinal & Const FelderLate-VariablenStatische Methoden & FelderGetter und SetterZusammenfassung – Bankkonto-Manager6Vererbung
Grundlagen der VererbungDas super-SchlüsselwortMethoden überschreibenDie @override-AnnotationDas final-Klassen-SchlüsselwortKonstruktoren & VererbungRückblick – Mitarbeiter-Hierarchie9Polymorphismus
Polymorphismus-GrundlagenPolymorphismus über InterfacesTypprüfung zur LaufzeitDie is & as OperatorenDas covariant SchlüsselwortZusammenfassung – Payment Processor