Bankingsystem
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 89 von 91.
Aufgabe
EinfachLass uns ein Bankensystem entwickeln, das Konten, Transaktionen und Überweisungen zwischen Konten verwaltet. Du erstellst ein System mit geeigneter Kapselung zum Schutz von Finanzdaten, Vererbung für verschiedene Kontotypen und Validierung, um die Datenintegrität sicherzustellen.
Du organisierst deinen Code auf sechs Dateien verteilt:
Transaction.php: Erstelle eineTransaction-Klasse, um Finanzvorgänge zu protokollieren. Verwende Konstruktor-Promotion fürtype(string: "deposit", "withdrawal" oder "transfer"),amount(float) undtimestamp(string). Alle Eigenschaften sollten öffentlich und schreibgeschützt sein. Füge eine MethodegetDescription(): stringhinzu, die"[type]: $[amount]"zurückgibt (formatiere den Betrag mit 2 Dezimalstellen).BankAccount.php: Binde die Transaction-Datei ein. Erstelle eine abstrakteBankAccount-Klasse mit:- Konstruktor-Promotion für
accountNumber(string, öffentlich und schreibgeschützt) undholderName(string, öffentlich und schreibgeschützt) - Eine geschützte
$balance-Eigenschaft, die mit 0.0 initialisiert wird - Ein privates Array zum Speichern des Transaktionsverlaufs
getBalance(): float: gibt den aktuellen Kontostand zurückdeposit(float $amount): string: addiert den Betrag zum Kontostand, protokolliert die Transaktion und gibt"Deposited: $[amount]"zurückabstract withdraw(float $amount): string: Unterklassen implementieren die Regeln für AbhebungenaddTransaction(Transaction $t): void: geschützte Methode zum Hinzufügen von Transaktionen zum VerlaufgetTransactionCount(): int: gibt die Anzahl der Transaktionen zurück
- Konstruktor-Promotion für
SavingsAccount.php: Binde die BankAccount-Datei ein. Erstelle eineSavingsAccount-Klasse, dieBankAccounterweitert, mit:- Eine Klassenkonstante
INTEREST_RATE, die auf 0.02 (2 %) gesetzt ist withdraw(float $amount): string: Wenn der Betrag den Kontostand übersteigt, gib"Insufficient funds"zurück; andernfalls ziehe den Betrag ab, protokolliere die Transaktion und gib"Withdrew: $[amount]"zurückapplyInterest(): string: berechnet die Zinsen auf den aktuellen Kontostand, fügt sie als Einzahlung hinzu und gibt"Interest applied: $[interest]"zurück
- Eine Klassenkonstante
CheckingAccount.php: Binde die BankAccount-Datei ein. Erstelle eineCheckingAccount-Klasse, dieBankAccounterweitert, mit:- Eine private
$overdraftLimit-Eigenschaft, die über den Konstruktor festgelegt wird (füge einen dritten Parameter mit dem Standardwert 100.0 hinzu) withdraw(float $amount): string: erlaubt eine Abhebung, wenn der Betrag den Kontostand plus das Überziehungslimit nicht überschreitet; gib bei einem Fehlschlag"Insufficient funds (overdraft limit: $[limit])"oder bei Erfolg"Withdrew: $[amount]"zurückgetOverdraftLimit(): float: gibt das Überziehungslimit zurück
- Eine private
Bank.php: Binde beide Kontodateien ein. Erstelle eineBank-Klasse, die Konten verwaltet:- Ein privates Array zum Speichern von Konten, indiziert nach Kontonummer
addAccount(BankAccount $account): void: fügt ein Konto hinzufindAccount(string $accountNumber): ?BankAccount: gibt das Konto oder null zurücktransfer(string $fromAccount, string $toAccount, float $amount): string: überweist Geld zwischen Konten. Gib"Source account not found","Destination account not found"oder bei einem Fehlschlag das Ergebnis der Abhebung zurück. Bei Erfolg zahle auf das Zielkonto ein und gib"Transferred $[amount] from [from] to [to]"zurück
main.php: Binde die Bank-Datei ein. Du erhältst zwei Eingaben: Kontodaten (JSON) und Vorgänge (JSON).Format des Konten-JSON:
[{"type": "savings", "number": "SAV001", "holder": "Alice", "initial": 1000}, {"type": "checking", "number": "CHK001", "holder": "Bob", "initial": 500, "overdraft": 200}]Format des Vorgänge-JSON:
[{"op": "deposit", "account": "SAV001", "amount": 200}, {"op": "withdraw", "account": "CHK001", "amount": 600}, {"op": "transfer", "from": "SAV001", "to": "CHK001", "amount": 300}, {"op": "interest", "account": "SAV001"}, {"op": "balance", "account": "SAV001"}]Erstelle die Bank und alle Konten (indem du die Anfangsbeträge einzahlst). Verarbeite jeden Vorgang:
"deposit": Gib das Ergebnis vondeposit()aus"withdraw": Gib das Ergebnis vonwithdraw()aus"transfer": Gib das Ergebnis vontransfer()aus"interest": Gib das Ergebnis vonapplyInterest()aus (nur für Sparkonten)"balance": Gib"[holder] balance: $[balance]"aus (2 Dezimalstellen)
Gib jedes Ergebnis in einer neuen Zeile aus. Formatiere alle Geldbeträge mit 2 Dezimalstellen.
Denke daran, dass Überweisungen atomar sein sollten: Wenn die Abhebung fehlschlägt, darf die Einzahlung nicht erfolgen. Die geschützte $balance-Eigenschaft ermöglicht es Unterklassen, sie zu ändern, während sie vor externem Code verborgen bleibt, und veranschaulicht damit eine geeignete Kapselung im finanziellen Kontext.
Probier es selbst
<?php
require_once 'Bank.php';
// Eingabe lesen
$accountsJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));
// JSON-Eingaben parsen
$accounts = (array)json_decode($accountsJson, true);
$operations = (array)json_decode($operationsJson, true);
// TODO: Eine Bank-Instanz erstellen
// TODO: Konten aus den Kontodaten erstellen
// Für jedes Konto in $accounts:
// - Wenn Typ "savings" ist, SavingsAccount erstellen
// - Wenn Typ "checking" ist, CheckingAccount erstellen (mit Überziehung, falls angegeben)
// - Konto zur Bank hinzufügen
// - Anfangsbetrag einzahlen
// TODO: Jede Operation verarbeiten
// Für jede Operation in $operations:
// - "deposit": Ergebnis von deposit() ausgeben
// - "withdraw": Ergebnis von withdraw() ausgeben
// - "transfer": Ergebnis von transfer() ausgeben
// - "interest": Ergebnis von applyInterest() ausgeben (nur für savings)
// - "balance": "[holder] balance: $[balance]" ausgeben (2 Dezimalstellen)
?>Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in OOPKlassen vs. ObjekteDas Schlüsselwort $thisMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick – Einfacher Taschenrechner4Vererbung
Grundlegende VererbungDas Schlüsselwort parent::MethodenüberschreibungDas Schlüsselwort finalAbstrakte KlassenRückblick – Mitarbeiterhierarchie7Kapselung
Öffentlich, geschützt, privatZugriffsmodifikatoren im DetailGetter und SetterInformationsverbergungKonstruktor-Promotion (8.0)Wiederholung – System zur Verwaltung von Schülerdatensätzen2Namespaces & Autoloading
Einführung in NamespacesDas use-SchlüsselwortPSR-4-Autoloading-StandardComposer-AutoloaderRückblick – Organisiertes Projekt5Schnittstellen & Verträge
Einführung in SchnittstellenSchnittstellen implementierenMehrere Schnittstellen implementierenSchnittstelle vs. abstrakte KlasseTyp-Hinweise mit SchnittstellenRückblick – Formrechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objektklonen__serialize & __unserializeRückblick – Benutzerdefinierte Sammlung11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenBenutzerdefinierte Exception-HierarchieTry, Catch, FinallyRückblick – Formularvalidator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klassen-Eigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenSchreibgeschützte Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphie
Methodenüberschreibung erneut betrachtetPolymorphie über SchnittstellenTyp-Hinweise & Union-TypenSpätes statisches BindenRückblick – Zahlungsabwickler9Traits
Einführung in TraitsMehrere Traits verwendenAuflösung von Trait-KonfliktenAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungÜbe selbstständig: Online-PHP-Compiler