In this assignment, a transfer method has been added to the ATM class of section 12.5:

public class ATM 
   /** 
      Transfers between the current account and the other account
      of the same customer.
      (Precondition: state is TRANSACT)
   */
   public void transfer(double value)
   {
      . . .
      back();
   }

Your task is to change the command-line user interface of the ATMSimulator so that the menu

A=Deposit, B=Withdrawal, C=Cancel: 

is replaced by

A=Deposit, B=Withdrawal, C=Transfer, D=Cancel: 

Of course, you should now carry out the appropriate actions when the user selects options C or D.

Complete the following file:

ATMSimulator.java

// TODO: Change the prompt "A=Deposit, B=Withdrawal, C=Cancel: " // to "A=Deposit, B=Withdrawal, C=Transfer, D=Cancel: " and implement // the transfer feature. import java.io.IOException; import java.util.Scanner; /** A text-based simulation of an automatic teller machine. */ public class ATMSimulator { public static void main(String[] args) { ATM theATM; try { Bank theBank = new Bank(); theBank.readCustomers("customers.txt"); theATM = new ATM(theBank); } catch(IOException e) { System.out.println("Error opening accounts file."); return; } Scanner in = new Scanner(System.in); while (true) { int state = theATM.getState(); if (state == ATM.START) { System.out.print("Enter customer number: "); int number = in.nextInt(); if (number == 0) return; theATM.setCustomerNumber(number); } else if (state == ATM.PIN) { System.out.print("Enter PIN: "); int pin = in.nextInt(); theATM.selectCustomer(pin); } else if (state == ATM.ACCOUNT) { System.out.print("A=Checking, B=Savings, C=Quit: "); String command = in.next(); if (command.equalsIgnoreCase("A")) theATM.selectAccount(ATM.CHECKING); else if (command.equalsIgnoreCase("B")) theATM.selectAccount(ATM.SAVINGS); else if (command.equalsIgnoreCase("C")) theATM.reset(); else System.out.println("Illegal input!"); } else if (state == ATM.TRANSACT) { System.out.println("Balance=" + theATM.getBalance()); System.out.print("A=Deposit, B=Withdrawal, C=Cancel: "); String command = in.next(); if (command.equalsIgnoreCase("A")) { System.out.print("Amount: "); double amount = in.nextDouble(); theATM.deposit(amount); theATM.back(); } else if (command.equalsIgnoreCase("B")) { System.out.print("Amount: "); double amount = in.nextDouble(); theATM.withdraw(amount); theATM.back(); } else if (command.equalsIgnoreCase("C")) theATM.back(); else System.out.println("Illegal input!"); } } } }

Use the following files:

ATM.java

/**
   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();
         otherAccount = currentCustomer.getSavingsAccount();
      }
      else
      {
         currentAccount = currentCustomer.getSavingsAccount();
         otherAccount = currentCustomer.getCheckingAccount();
      }
      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)
   {  
      assert state == TRANSACT;
      currentAccount.withdraw(value);
      otherAccount.deposit(value);
   }
   
   /** 
      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 BankAccount otherAccount;
   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;
}

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;
}