銀行システム
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 85/87。
この課題では、OOPの原則を使用して現実世界の金融業務をモデル化する銀行システムを構築します。
システムは、SavingsAccountやCheckingAccountのような異なるアカウント型を処理し、どちらも base Accountクラスを拡張する必要があります。それぞれのアカウント型には固有の動作があります。たとえば、貯蓄アカウントでは利息が付く一方、当座アカウントでは当座貸越保護が提供される場合があります。
取引をどのようにモデル化するか考えてみましょう。Transactable のようなインターフェースでは、deposit() や withdraw() のメソッドを定義できます。無効な操作を適切に処理するために、InsufficientFundsException のようなカスタム例外の使用を検討してください。
Bank クラスは複数の口座と顧客を管理し、コンポジションを示すことがあります。Factory パターンを適用してさまざまな口座タイプを作成したり、Observer パターンを使用して口座の変更を顧客に通知したりできます。
残高や口座番号などの機密データを保護するためにカプセル化に重点を置き、ポリモーフィズムを使用して異なる口座タイプを一様に処理します。
チャレンジ
簡単OOPの原則を習得したことを示す、完全な Banking System を構築しましょう!さまざまな account type、transaction handling、適切な exception management を備えた system を作成し、すべてを複数のファイルに整理します。
コードを7つのファイルに整理します。
Transactable.java: financial operations の contract を定義する interface を作成します。deposit(double amount)とwithdraw(double amount)のメソッドを宣言し、どちらも成功を示す boolean を返すようにします。InsufficientFundsException.java:Exceptionを拡張する custom exception を作成します。constructor は attempted withdrawal amount と current balance を受け取り、Insufficient funds: attempted [amount], available [balance]という形式の message を作成するようにします。Account.java: 任意の bank account を表す abstract base class を作成します。accountNumber(String) とbalance(double) の private field、両方を初期化する constructor、適切な getter、subclass が変更できるようにした balance 用の protected setter、そして String を返す abstract methodgetAccountType()を含めます。balance を小数点以下2桁でフォーマットし、"[accountNumber] ([accountType]): $[balance]"を返すgetDetails()method を実装します。SavingsAccount.java:Accountを拡張し、Transactableを実装する class を作成します。interestRate(double) 用の private field を追加します。constructor は accountNumber、initial balance、interestRate を受け取ります。getAccountType()は"Savings"を返すように実装します。deposit()では amount を balance に加えて true を返します。withdraw()では、amount が balance を超える場合は false を返し、それ以外の場合は差し引いて true を返します。applyInterest()method を追加し、balance * interestRateによって balance を増加させます(rate は fraction として保存されるため、0.05は 5% を意味します)。CheckingAccount.java:Accountを拡張し、Transactableを実装する class を作成します。overdraftLimit(double) 用の private field を追加します。constructor は accountNumber、initial balance、overdraftLimit を受け取ります。getAccountType()は"Checking"を返すように実装します。deposit()では amount を加えて true を返します。withdraw()では、amount が balance に overdraftLimit を加えた値以下の場合に withdrawal を許可し、この limit を超える場合は false を返します。Bank.java: ArrayList を使用して accounts を管理する class を作成します。次の methods を含めます。addAccount(Account account)- account を bank に追加しますfindAccount(String accountNumber)- Account を返し、見つからない場合は null を返しますtransfer(String fromAccount, String toAccount, double amount)- accounts 間で money を transfer し、source account の funds が不足している場合はInsufficientFundsExceptionを throw します。成功時は"Transferred $[amount] from [fromAccount] to [toAccount]"を返しますgetTotalDeposits()- すべての account balances の合計を返します
Main.java: banking system を構築します!comma-separated string of commands を受け取ります。SAVINGS:accountNumber:balance:interestRateCHECKING:accountNumber:balance:overdraftLimitDEPOSIT:accountNumber:amountWITHDRAW:accountNumber:amountTRANSFER:fromAccount:toAccount:amountINTEREST:accountNumber
各 command を処理し、次の内容を print します。
- SAVINGS/CHECKING:
Account created: [accountNumber] - DEPOSIT:
Deposited $[amount] to [accountNumber] - WITHDRAW: 成功時は
Withdrew $[amount] from [accountNumber]、失敗時はWithdrawal failed: [accountNumber] - TRANSFER: success message または
Transfer failed: [exception message]を print します - INTEREST:
Interest applied to [accountNumber]
すべての commands の後に
--- Bank Summary ---を print し、続けて各 account の details(getDetails()を使用)を表示し、最後にTotal deposits: $[total]を小数点以下2桁でフォーマットして表示します。
入力として1つの comma-separated command string を受け取ります。
たとえば、入力が 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 の場合、出力は次のようになります。
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.50checking account では、balance が $500 しかないにもかかわらず $600 の withdrawal が可能になっていることに注目してください。これが overdraft protection の動作です!transfer 後、savings account は balance に対して 5% の interest を得ています。この challenge では、inheritance、interfaces、polymorphism、custom exceptions、encapsulation を、現実的な banking application に組み合わせています!
自分で試してみよう
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// TODO: Bankインスタンスを作成する
// TODO: 入力をカンマで分割して個々のコマンドを取得する
// TODO: 各コマンドを処理する:
// - SAVINGS:accountNumber:balance:interestRate -> Create SavingsAccount, print "Account created: [accountNumber]"
// - CHECKING:accountNumber:balance:overdraftLimit -> Create CheckingAccount, print "Account created: [accountNumber]"
// - DEPOSIT:accountNumber:amount -> 入金して "Deposited $[amount] to [accountNumber]" を出力する
// - WITHDRAW:accountNumber:amount -> Withdraw and print success or "Withdrawal failed: [accountNumber]"
// - TRANSFER:fromAccount:toAccount:amount -> 振替して成功を出力するか "Transfer failed: [exception message]" を出力する
// - INTEREST:accountNumber -> Apply interest and print "Interest applied to [accountNumber]"
// TODO: すべてのコマンドの後、"--- Bank Summary ---" を出力する
// TODO: getDetails() を使って各口座の詳細を出力する
// TODO: Print "Total deposits: $[total]" formatted to 2 decimal places
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造自分で練習してみよう: Javaオンラインコンパイラ