CS161 Programming Assignment 3: Inheritance

Due - 9/18 @ 8:00pm

Late - 9/20 @ 8:00am


1. Goal

The goal of this assignment is to understand the concept of inheritance in Java. You will create subclasses to override and add new methods to the subclasses.

2. Description

Consider a hierarchy of bank account classes as shown in the figure below.

Bank Account Hierarchy

You will implement the four classes, Account, SavingsAccount, CheckingAccount, and MoneyMarketAccount.

2.1 Account class

Ideally, Account should be an abstract class. However, since we have not yet covered the topic in our lectures and recitations, you must implement Account as a concrete class. You will also notice that we are using a general Exception class with different messages to signify error cases. This is not considered good practice. Later in this course, we will show you how to create custom Exceptions, and use them in an extended version of the assignment.

List of attributes:

  1. protected String id; // some form of account identification
  2. protected double balance; // stores the current balance

The constructor should be of the form:
public Account(String id, double initialBalance)

List of methods:

  1. public void withdraw(double amount) throws Exception // The provided amount gets taken out of the account as a result of an ATM transaction. No transaction fees apply. Assume amount is greater than 0. You will declare the "throws Exception" clause even though the implementation will not throw "Exception". The subclasses might throw an Exception.
  2. public void deposit(double amount) throws Exception // The provided amount is added to the account as a result of an ATM transaction. No transaction fees apply. Assume amount is greater than 0. You will declare the "throws Exception" clause even though the implementation will not throw "Exception". The subclasses might throw an Exception.
  3. public String getID() // Returns the account id.
  4. public double getBalance() // Returns the current balance.

2.2 SavingsAccount class

This type of account requires a minimum of $10 in the account. This account allows for depositing or withdrawing from ATM machines. No fees are charged for depositing. Withdrawing money incurs a transaction fee of $2 per withdrawal that is taken out of the balance. Any withdrawal that causes the balance to go below $10 (because of the amount to be withdrawn plus the fee) is disallowed. Interest amount is calculated and added to the balance every quarter.

The constructor should be of the form:
public SavingsAccount(String id, double initialBalance) throws Exception

The initial balance cannot be less than $10. If it is, then a new Exception is thrown with the message, "Insufficient starting balance" (i.e., throw new Exception("Insufficient starting balance");) and the account is not created.

No new attributes are needed. Override the withdraw method to incorporate the transaction fee for ATM withdrawals. A withdrawal that potentially lowers the balance below $10 is not allowed, and an Exception is thrown with the message "Insufficient funds (10)". The deposit method can be inherited.

Add the following method:

  1. public double addInterest(double rate) // the quarterly rate is provided as a percentage by the caller of the method. The method calculates the interest on the balance and adds the interest to the balance. The return value of the method is the interest that was calculated (not the new balance, just the interest). Note that the caller takes care of determining when a month is over. The addInterest method only needs to be aware of the formula to calculate interest (= balance*rate_in_percent/100.). For example, if the quarterly rate of interest is 0.25%, and the balance is $10,000, then the interest is $25, and the new balance becomes $10,025.

2.3 CheckingAccount class

This account does not give any interest. It allows deposit and withdrawals through ATM machines, which incurs a fee of $1 per transaction, which is deducted from the balance. The balance cannot go below 0. An exception with the message "Insufficient balance (0)" is thrown if a withdraw may cause the balance to go below 0.

The constructor should be of the form:
public CheckingAccount(String id, double initialBalance) throws Exception

Checks may be used to make withdrawals. The first three check uses in a month are free, but subsequent uses add a fee of $2 to each check withdrawal. ATM withdrawals can take the balance down to zero but not below. Only checks are allowed to take the balance to -$10 (i.e., an overdraft). One or more checks can bring the balance down to -$10, but not lower. If a check use potentially lowers the balance below -$10, the check is disallowed and an Exception is thrown with the message "Insufficient funds (-10)".

Tracking how many checks are used in a month requires a new attribute and methods. Implement the following attribute:

  1. private int numberOfChecksUsed; // stores the number of checks used every month. Starts at 0, and can be reset using a method below.

The initial balance cannot be negative. If it is negative, a new Exception is thrown with the error message, "Negative balance", and the account is not created.

Override deposit and withdraw methods as needed to incorporate the new rules for CheckingAccount. In addition, add the following new methods:

  1. public void resetChecksUsed() // This method makes the numberOfChecksUsed zero.
  2. public void withdrawUsingCheck(double amount) throws Exception // This method allows one to use checks to withdraw cash. It updates the balance according to the rules described above.

2.4 MoneyMarketAccount class

A money market account gives you higher interest, but offers a limited number of deposits and withdrawsls. A maximum of 6 transactions (deposits or withdrawals) is allowed per month. If a withdrawal causes the balance to go below $10,000, a fee of $100 is imposed and no more transactions are allowed until the balance is increased using a deposit transaction. A deposit performed to reach or exceed the minimum balance is not counted as part of the 6 transactions.

The constructor should be of the form:
public MoneyMarketAccount(String id, double initialBalance) throws Exception

The initial balance cannot be less than $10,000. If it is, then a new Exception is thrown with the error message, "Insufficient starting balance", and the account is not created.

Add an attribute to track the number of transactions:
private int numberOfTransactions; // store how many deposits and withdrawals were performed

Override the deposit and withdraw methods to take into account the constraint on the number of transactions as well as the minimum balance requirement. If a deposit or withdraw cannot be performed because of too many transactions, then an Exception is thrown with the message "Exceeding allowed transactions (6)". If a withdrawal is denied because of minimum balance problems, then throw an Exception with the message "Below minimum balance".

Add the following methods:

  1. public double addInterest(double rate) // the monthly rate is known to and provided by the caller. The method calculates the interest on the balance and adds the interest to the balance. The method returns the interest that was calculated.
  2. public void resetNumberOfTransactions() // resets the number of transactions to zero. Note that the main method will take care of calling this method at the appropriate time and thus, the method implementation does not need to track months.

3. General Information

None of the methods above should be declared static. In fact, compilation of your program will fail if the method signatures in your program are different than above.

Constructors in the subclasses should make appropriate calls the the superclass'constructor rather than do the work themselves.

Keep in mind that we will not test your main method -- the methods you implement will be tested directly. Ideally, you should create your own main methods, perhaps one in each class, to test each class separately. You can also write another main method in a separate class that tests the four classes together.

Here is a sample barebones main method for the Account class. It does not test all the methods, nor does it test for various situations.

public static void main(String[] args) {
    Account a1 = new Account ("csclub", 200.05);
    try {
        a1.withdraw(10);
    } catch(Exception e) {
        System.err.println(e);
    }
    System.out.println("Remaining balance in " + a1.getID() + "'s account: $" + a1.getBalance());
}

Here is a sample barebones main method for the SavingsAccount class. It does not test all the methods, nor does it test for various situations.

public static void main(String[] args) {
        SavingsAccount a1 = null;
        try {
            a1 = new SavingsAccount ("ghosh", 2000.05);
        } catch(Exception e) {
            System.err.println(e);
        }
        try {
            a1.deposit(10);
        } catch (Exception e) {
            System.err.println(e);
        }
        double interest = a1.addInterest(0.75);
        System.out.println("Interest: " + interest);
        System.out.println("Remaining balance in " + a1.getID() + "'s account: $" + a1.getBalance());
}

Submission

Create a single jar file called P3.jar from the four Java files (Account, SavingsAccount, CheckingAccount, and MoneyMarketAccount).
Do not add other files (e.g., class files). Submit the P3.jar file via the online checkin system.