import java.math.*; /** This class represents a general bank account. It abstracts state and behavior that is common to savings, checking, and other sorts of accounts. Subclasses must implement abstract methods, and supply additional state and behavior that applies to particular account types. E.g., if an account pays interest, the rate and method of calculating it must be implemented. */ public abstract class BankAccount implements Comparable { /** Holds the state of the account. If true (default), the account is active (open); if false, it is closed. */ private boolean active; /** Holds the account balance amount. Note that the amount may be negative in the case of account types permitting overdrafts. */ private BigDecimal balance; /** Holds the account number. Account number must be unique across all accounts. */ private String accountNumber; /** Holds the Name instance identifying the account holder. */ private Name name; /** Holds the Address instance for the account holder's address of record. */ private Address address; /** Create a new empty account. Set the new account active. */ BankAccount() { active = true; } /** CLose the account by setting active to false and the balance to zero. Return the balance value as it was before closing. The expectation is that the invoker is paying the balance account to the customer. */ public BigDecimal close() { BigDecimal result = balance; setBalance( new BigDecimal(0.0) ); active = false; return result; } /** Compare this account to anObject, assumed to be a BankAccount. Return -1, 0, or 1 if this account should sort before, in the same position as, or after anObject. */ public int compareTo(Object anObject) { return getAccountNumber().compareTo(((BankAccount)anObject).getAccountNumber() ); } /** Deposit anAmount to this account. Increment the balance by anAmount. public void deposit(BigDecimal anAmount) { setBalance( getBalance().add(anAmount) ); } /** Return true if this account is the same as an Object, assumed to be a BankAccount. Two accounts are the same if they have the same account number. Note that equals() must be consistent with compareTo(). */ public boolean equals(Object anObject) { return getAccountNumber().equals(((BankAccount)anObject).getAccountNumber()); } /** Return the account number. */ public String getAccountNumber() { return accountNumber; } /** Return the account type. Concrete subclasses must implement this method. */ public abstract String getAccountType(); /** Return the account holder's address. */ public Address getAddress() { return address; } /** Return the current balance amount. */ public BigDecimal getBalance() { return balance; } /** Return the account holder's name. */ public Name getName() { return name; } /** Return the maximum withdrawal amount. Concrete subclasses must implement this method. */ public abstract BigDecimal getWithdrawalLimit(); /** Set the current balance amount. */ public void setBalance(BigDecimal anAmount) { balance = anAmount.setScale(2, BigDecimal.ROUND_HALF_DOWN); } /** Return true if the account is active (open), false if closed. */ public boolean isActive() { return active; } /** Set the account number. */ public void setAccountNumber(String aNumber) { accountNumber = aNumber; } /** Set the account holder's address. */ public void setAddress(Address anAddress) { address = anAddress; } /** Set the account holder's name. */ public void setName(Name aName) { name = aName; } /** Withdraw (reduce the current balance by) an amount. Return true if the withdrawal was done, false if not (if the amount was too large). */ public boolean withdraw(BigDecimal anAmount) { boolean result; if (result = ( getWithdrawalLimit().compareTo(anAmount) > 0 )) setBalance( getBalance().subtract(anAmount) ); return result; } }