Add the capability of transferring money from the currently selected account to the other account from the same account holder to the ATM class of Section 12.5.

You need not implement any user interface.

Complete the following file:

ATM.java

// TODO: Implement the transfer method. If required, add data fields and // modify methods /** An ATM that accesses a bank. */ public class ATM { /** Constructs an ATM for a given bank. @param aBank the bank to which this ATM connects */ public ATM(Bank aBank) { theBank = aBank; reset(); } /** Resets the ATM to the initial state. */ public void reset() { customerNumber = -1; currentAccount = null; state = START; } /** Sets the current customer number and sets state to PIN. (Precondition: state is START) @param number the customer number. */ public void setCustomerNumber(int number) { assert state == START; customerNumber = number; state = PIN; } /** Finds customer in bank. If found sets state to ACCOUNT, else to START. (Precondition: state is PIN) @param pin the PIN of the current customer */ public void selectCustomer(int pin) { assert state == PIN; currentCustomer = theBank.findCustomer(customerNumber, pin); if (currentCustomer == null) state = START; else state = ACCOUNT; } /** Sets current account to checking or savings. Sets state to TRANSACT. (Precondition: state is ACCOUNT or TRANSACT) @param account one of CHECKING or SAVINGS */ public void selectAccount(int account) { assert state == ACCOUNT || state == TRANSACT; if (account == CHECKING) currentAccount = currentCustomer.getCheckingAccount(); else currentAccount = currentCustomer.getSavingsAccount(); state = TRANSACT; } /** Withdraws amount from current account. (Precondition: state is TRANSACT) @param value the amount to withdraw */ public void withdraw(double value) { assert state == TRANSACT; currentAccount.withdraw(value); } /** Deposits amount to current account. (Precondition: state is TRANSACT) @param value the amount to deposit */ public void deposit(double value) { assert state == TRANSACT; currentAccount.deposit(value); } /** Transfers between the current account and the other account of the same customer. (Precondition: state is TRANSACT) */ public void transfer(double value) { // TODO } /** Gets the balance of the current account. (Precondition: state is TRANSACT) @return the balance */ public double getBalance() { assert state == TRANSACT; return currentAccount.getBalance(); } /** Moves back to the previous state. */ public void back() { if (state == TRANSACT) state = ACCOUNT; else if (state == ACCOUNT) state = PIN; else if (state == PIN) state = START; } /** Gets the current state of this ATM. @return the current state */ public int getState() { return state; } private int state; private int customerNumber; private Customer currentCustomer; private BankAccount currentAccount; private Bank theBank; public static final int START = 1; public static final int PIN = 2; public static final int ACCOUNT = 3; public static final int TRANSACT = 4; public static final int CHECKING = 1; public static final int SAVINGS = 2; }

Use the following files:

ATMTester.java

import java.io.IOException;

public class ATMTester
{
   public static void main(String[] args) throws IOException
   {
      Bank bank = new Bank();
      bank.readCustomers("customers.txt");
      ATM atm = new ATM(bank);
      atm.setCustomerNumber(1);
      atm.selectCustomer(1234);
      atm.selectAccount(ATM.SAVINGS);
      atm.deposit(4000);
      atm.transfer(2000);
      System.out.println("Savings: " + atm.getBalance());
      System.out.println("Expected: 2000");
      atm.back();
      atm.selectAccount(ATM.CHECKING);      
      atm.transfer(500);
      System.out.println("Checking: " + atm.getBalance());
      System.out.println("Expected: 1500");
      atm.back();
      atm.selectAccount(ATM.SAVINGS);      
      System.out.println("Savings: " + atm.getBalance());
      System.out.println("Expected: 2500");
   }
}

Bank.java

import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

/**
   A bank contains customers with bank accounts.
*/
public class Bank
{  
   /**
      Constructs a bank with no customers.
   */
   public Bank()
   {  
      customers = new ArrayList<Customer>();
   }
   
   /**
      Reads the customer numbers and pins 
      and initializes the bank accounts.
      @param filename the name of the customer file
   */
   public void readCustomers(String filename) 
         throws IOException
   {  
      Scanner in = new Scanner(new FileReader(filename));
      while (in.hasNext())
      {  
         int number = in.nextInt();
         int pin = in.nextInt();
         Customer c = new Customer(number, pin);
         addCustomer(c);
      }
      in.close();
   }
   
   /**
      Adds a customer to the bank.
      @param c the customer to add
   */
   public void addCustomer(Customer c)
   {  
      customers.add(c);
   }
   
   /** 
      Finds a customer in the bank.
      @param aNumber a customer number
      @param aPin a personal identification number
      @return the matching customer, or null if no customer 
      matches
   */
   public Customer findCustomer(int aNumber, int aPin)
   {  
      for (Customer c : customers)
      {  
         if (c.match(aNumber, aPin))
            return c;
      }
      return null;
   }

   private ArrayList<Customer> customers;
}

BankAccount.java

/**
   A bank account has a balance that can be changed by 
   deposits and withdrawals.
*/
public class BankAccount
{  
   /**
      Constructs a bank account with a zero balance.
   */
   public BankAccount()
   {  
      balance = 0;
   }

   /**
      Constructs a bank account with a given balance.
      @param initialBalance the initial balance
   */
   public BankAccount(double initialBalance)
   {  
      balance = initialBalance;
   }
 
   /** 
      Deposits money into the account.
      @param amount the amount of money to withdraw
   */
   public void deposit(double amount) 
   {  
      balance = balance + amount;
   }

   /** 
      Withdraws money from the account.
      @param amount the amount of money to deposit
   */
   public void withdraw(double amount) 
   {  
      balance = balance - amount;
   }

   /** 
      Gets the account balance.
      @return the account balance
   */
   public double getBalance()
   {  
      return balance; 
   }

   private double balance; 
}

Customer.java

/**
   A bank customer with a checking and a savings account.
*/
public class Customer
{  
   /**
      Constructs a customer with a given number and PIN.
      @param aNumber the customer number
      @param aPin the personal identification number
   */
   public Customer(int aNumber, int aPin)
   {  
      customerNumber = aNumber;
      pin = aPin;
      checkingAccount = new BankAccount();
      savingsAccount = new BankAccount();
   }
   
   /** 
      Tests if this customer matches a customer number 
      and PIN.
      @param aNumber a customer number
      @param aPin a personal identification number
      @return true if the customer number and PIN match
   */
   public boolean match(int aNumber, int aPin)
   {  
      return customerNumber == aNumber && pin == aPin;
   }
   
   /** 
      Gets the checking account of this customer.
      @return the checking account
   */
   public BankAccount getCheckingAccount()
   {  
      return checkingAccount;
   }
   
   /** 
      Gets the savings account of this customer.
      @return the checking account
   */
   public BankAccount getSavingsAccount()
   {  
      return savingsAccount;
   }

   private int customerNumber;
   private int pin;
   private BankAccount checkingAccount;
   private BankAccount savingsAccount;
}