|
|
|
Sponsored Link •
|
|
Advertisement
|
As an example of when an interface isn't exactly what you want, use LinkMap and Map. Couldn't use Map because of RemoteException.
Bootsie IS-A Dog
Car IS-AN Automobile
OverdraftAccount ObjectOverdraftAccount IS-AN Account
OverdraftAccount has the same interface and fulfills the
same semantic contract as Account
OverdraftAccount fulfills the semantic contract
differently than Account
1 package com.artima.examples.account.ex1;
2
3 /**
4 * Represents a bank account with overdraft protection. Instances
5 * of this class are instantiated with a specified maximum
6 * overdraft. If a client attempts to withdraw more than the
7 * current account balance, the bank may loan the amount in
8 * excess of the balance to the client. The overdraft maximum
9 * passed to an <code>OverdraftAccount</code>'s constructor
10 * is the maximum amount the bank will lend to the client in
11 * this manner. When a client makes a deposit, the bank will
12 * pay itself back first before increasing the account's balance.
13 *
14 * <p>
15 * As described in class <code>Account</code>, money is stored in
16 * this account in integral units. Clients
17 * can use this account to store any kind of value, such as money
18 * or points, etc. The meaning of the integral units stored in
19 * this account is a decision of the client that instantiates the
20 * account. The maximum amount of units that can be stored as
21 * the current balance of an <code>Account</code> is Long.MAX_VALUE.
22 */
23 public class OverdraftAccount extends Account {
24
25 /**
26 * The maximum amount the bank will loan to the client.
27 */
28 private final long overdraftMax;
29
30 /**
31 * The current amount the bank has loaned to the client
32 * which has not yet been repaid. This must be zero to
33 * overdraftMax.
34 */
35 private long overdraft;
36
37 /**
38 * Constructs a new <code>OverdraftAccount</code> with the
39 * passed <code>overdraftMax</code>.
40 *
41 * @param overdraftMax the maximum amount the bank will loan
42 * to the client
43 */
44 public OverdraftAccount(long overdraftMax) {
45 this.overdraftMax = overdraftMax;
46 }
47
48 /**
49 * Returns the current overdraft, the amount the bank has
50 * loaned to the client that has not yet been repaid.
51 *
52 * @returns the current overdraft
53 */
54 public long getOverdraft() {
55 return overdraft;
56 }
57
58 /**
59 * Returns the overdraft maximum, the maximum amount the
60 * bank will allow the client to owe it. For each instance
61 * of <code>OverdraftAccount</code>, the overdraft maximum
62 * is constant.
63 *
64 * @returns the overdraft maximum
65 */
66 public long getOverdraftMax() {
67 return overdraftMax;
68 }
69
70 /**
71 * Withdraws exactly the passed amount from the
72 * <code>Account</code>. If the passed amount is
73 * less than or equal to the current balance, all withdrawn
74 * funds will be taken from the balance, and the balance
75 * will be decremented by the passed amount. If the passed amount
76 * exceeds the current balance, the bank may loan the client the
77 * difference. The bank will make the loan only if the difference
78 * between the passed amount and the balance is less than or equal to
79 * the available overdraft. The available overdraft is equal to
80 * the current overdraft (the amount already loaned to the client and
81 * not yet repaid), subtracted from the overdraft maximum, which
82 * is passed to the constructor of any <code>OverdraftAccount</code>.
83 *
84 * <p>
85 * If the passed amount less the current balance is less than or equal
86 * to the available overdraft, the <code>withdraw</code> method returns
87 * the requested amount, sets the current balance to zero, and records
88 * the loan. Otherwise, if the passed amount less the current balance
89 * exceeds the available overdraft, the <code>withdraw</code> method throws
90 * <code>InsufficientFundsException</code>.
91 *
92 * @param amount amount to withdraw
93 * @returns amount withdrawn from the <code>Account</code>
94 * @throws InsufficientFundsException if the <code>Account</code>
95 * contains insufficient funds for the requested withdrawal
96 */
97 public long withdraw(long amount)
98 throws InsufficientFundsException {
99
100 long balance = getBalance();
101 if (balance >= amount) {
102
103 // Balance has sufficient funds, just take the
104 // money from the balance.
105 balance -= amount;
106 return amount;
107 }
108
109 long shortfall = amount - balance;
110 long extraAvailable = overdraftMax - overdraft;
111
112 if (shortfall > extraAvailable) {
113 throw new InsufficientFundsException(shortfall - extraAvailable);
114 }
115 overdraft += shortfall;
116 super.withdraw(amount - shortfall);
117
118 return amount;
119 }
120
121 /**
122 * Deposits exactly the passed amount into the <code>Account</code>.
123 * If the current overdraft is zero, the balance will be increased
124 * by the passed amount. Otherwise, the bank will attempt to pay
125 * off the overdraft first, before increasing the current balance
126 * by the amount remaining after the overdraft is repaid, if any.
127 *
128 * <p>
129 * For example, if the balance is 200, the overdraft is 100, and the
130 * <code>deposit</code> method is invoked with a passed <code>amount</code>
131 * of 50, the bank would use all 50 of those monetary units to pay down
132 * the overdraft. The overdraft would be reduced to 50 and the balance would
133 * remain at 200. If subsequently, the client deposits another 100 units,
134 * the bank would use 50 of those units to pay off the overdraft loan and
135 * direct the remaining 50 into the balance. The new overdraft would
136 * be 0 and the new balance would be 250.
137 *
138 * @param amount amount to deposit
139 * @throws ArithmeticException if requested deposit would cause the
140 * balance of this <code>Account</code> to exceed Long.MAX_VALUE.
141 */
142 public void deposit(long amount) {
143 if (overdraft > 0) {
144 if (amount < overdraft) {
145 overdraft -= amount;
146 }
147 else {
148 long diff = amount - overdraft;
149 overdraft = 0;
150 super.deposit(diff);
151 }
152 }
153 else {
154 super.deposit(amount);
155 }
156 }
157 }
OverdraftAccount object on the heap:
Manager IS-AN Employee
Peon IS-AN Employee
RedCup IS-A Cup
BlueCup IS-A Cup
Account balance is $5000)
OverDraftAccount)
StampMachine.State family
Account in the solution.
Square IS-A Rectangle?
Wouldn't want to say: Overdraft100Account, Overdraft500Account, and Overdraft1000Account if there were just three legal overdraft maxes. Just use OverdraftAccount that takes a max. And either allow client to establish legal values for overdraft (other than negative), or check at constructor for legal values.
Account a = new OverdraftAccount(50000);
|
Sponsored Links
|