import java.text.NumberFormat; public abstract class Account implements Cloneable { //Instance data private String number; private double balance; //Constructors public Account(double balance) { if (balance < 0.0) throw new RuntimeException("Initial Balance cannot be negative"); this.number = nextAccountNumber(); this.balance = balance; } public Account() { this(0.0); } //Accessors public String getNumber() { return this.number; } public double getBalance() { return this.balance; } public abstract void deposit(double amount); public abstract void withdraw(double amount); //Mutators protected void credit(double amount) { if (amount < 0.0) throw new RuntimeException("CREDIT amount cannot be negative"); this.balance += amount; } protected void debit(double amount) { if (amount < 0.0) throw new RuntimeException("DEBIT amount cannot be negative"); this.balance -= amount; } public void transfer(double amount, Account source) { source.withdraw(amount); this.deposit(amount); } //Over-ride of the toString() method private static NumberFormat fmt = NumberFormat.getCurrencyInstance(); public String toString() { return padding(this.getClass().getName(), 15) + " " + this.getNumber() + " Balance: " + fmt.format(this.getBalance()); } private static String padding(String str, int width) { while (str.length() < width) str += " "; return str; } public boolean equals(Object other) { if (other == null) return false; if (other.getClass() != this.getClass()) return false; Account that = (Account)other; return this.balance == that.balance && this.number.equals(that.number); } public Object clone() { try { Account twin = (Account)super.clone(); return twin; } catch (CloneNotSupportedException cx) { return null; } } //Helpers //Automatically create a new account number private static int lastNumber = 6000000; private static String nextAccountNumber() { String nbr = "" + (lastNumber++); nbr = nbr.substring(0,1) + "-" + nbr.substring(1,4) + "-" + nbr.substring(4); return nbr; } }