Background: For this lab, you will use the provided versions of the BankAccount,
ID: 3859675 • Letter: B
Question
Background: For this lab, you will use the provided versions of the BankAccount, CheckingAccount, and SavingsAccount classes (modified from the versions we developed in class), as well as the provided text files “accounts.txt” and “broken_accounts.txt”. You will need to use the GregorianCalendar class discussed in class, as well as several of the String methods we discussed (specifically split).
In addition, you will need to know how to compute compound interest rates. The formula is as follows: B = B(1 +r/365)^n
B= Starting Balance
r = Interest rate
n = Number of days since account was opened
B = Current Balance
Part 1: Create a class called “CompoundInterestAccount” that extends BankAccount. CompoundInterestAccount should have a constructor that takes a double representing the balance, an integer that represents the account number, and a GregorianCalendar object that represents the date the account was opened as parameters.
public CompoundInterestAccount(double b, int accountNumber, GregorianCalendar c){
This class should use the current date to compute the balance of each account. Note that this must be done every time the balance is referenced. You must assume that this account will exist and be used for a long time, so computing the new balance once is not good enough. The easiest way to accomplish this is to override the getBalance method and compute the current balance whenever it is requested. To accomplish this, you need to store the date of the last time the balance was computed. That way you can apply the formula above as if the last computed balance was the initial balance, and the days since it was last computed is the number of days since it was opened. Since the new getBalance method needs to store the newly computed balance and the current date, you will need to add a protected mutator for the balance attribute in the BankAccount class. The withdraw and deposit methods will need to be overridden as well.
Part 2: Write a main method in a new class that reads the “accounts.txt” file and creates an account for each line in it. You should create a method in the same class as the main method called “createAccount” that takes a line from the accounts file as a parameter and returns a BankAccount object. The format of the file is as follows:<account type>,<account number>,<initial balance>,[<year>,<month>,<day>] (The year, month, and day values represent the date the account was opened, and are only present if the account is a CompoundInterestAccount)
The account type will be represented by a single character. “C” indicates a CheckingAccount, “S” indicates a SavingsAccount, and “I” indicates a CompoundInterestAccount.
Add each line to an ArrayList of BankAccount objects in the main method and print each of them using the toString method.
Part 3: Create an “InvalidAccountTypeException” class that extends “Exception”. This should be thrown by the createAccount method when the account type provided is invalid. You can use “broken_accounts.txt” to test this. When an InvalidAccountTypeException is caught in the main method, a simple error message should be printed, but the program should continue, and create the rest of the accounts that are valid.
accounts.txt:
S,589,940.0844439861934
S,138,779.289144078138
C,756,415.5529462180044
C,646,781.4432071068333
I,942,442.10646742813185,2002,3,21
I,13,899.8939435285605,1954,12,28
I,267,820.1097723760814,1959,6,23
S,452,339.1252964992141
I,438,276.69504219454024,1986,12,11
C,678,645.7116146769681
Bankaccount.java:
public abstract class BankAccount{
private int accountNumber;
private double balance;
public BankAccount(double initialDeposit, int accountNumber){
balance = initialDeposit;
this.accountNumber = accountNumber;
}
public double getBalance(){
return balance;
}
public int getAccountNumber(){
return accountNumber;
}
public boolean withdraw(double amt){
if(amt > balance) return false;
balance -= amt;
return true;
}
public void deposit(double amt){
balance += amt;
}
}
Brokenaccount.txt:
S,589,940.0844439861934
S,138,779.289144078138
C,756,415.5529462180044
C,646,781.4432071068333
M,942,442.10646742813185,2002,3,21
I,13,899.8939435285605,1954,12,28
I,267,820.1097723760814,1959,6,23
Q,452,339.1252964992141
I,438,276.69504219454024,1986,12,11
C,678,645.7116146769681
Checkingaccount.java:
public class CheckingAccount extends BankAccount{
private int checksWritten;
public CheckingAccount(double initialDeposit, int accountNumber){
super(initialDeposit, accountNumber);
}
protected boolean writeCheck(double amt){
checksWritten++;
return withdraw(amt);
}
public String toString(){
return "Checking Account #" + getAccountNumber() +": " + getBalance();
}
}
SavingAccount.java:
public class SavingsAccount extends BankAccount{
public SavingsAccount(double amt, int accountNumber){
super(amt, accountNumber);
}
public String toString(){
return "Savings Account #" + getAccountNumber() +": " + getBalance();
}
}
Explanation / Answer
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.GregorianCalendar;
import java.util.concurrent.TimeUnit;
/**
*
* @author Sam
*/
public class CompoundInterestAccount extends BankAccount{
GregorianCalendar openDate;
GregorianCalendar lastUpdate;
public final static int RATE = 4;
public CompoundInterestAccount(double initialDeposit, int accountNumber, GregorianCalendar openDate) {
super(initialDeposit, accountNumber);
this.openDate = openDate;
lastUpdate = openDate;
}
@Override
public double getBalance() {
double balance = super.getBalance();
GregorianCalendar today = new GregorianCalendar();
balance = balance * Math.pow((1 +RATE/365),TimeUnit.MICROSECONDS.toDays(today.compareTo(lastUpdate)));
lastUpdate = today;
setBalance(balance);
return balance;
}
@Override
public boolean withdraw(double amt) {
double balance = getBalance();
if (amt > balance) {
return false;
}
balance -= amt;
setBalance(balance);
return true;
}
@Override
public void deposit(double amt) {
double balance = getBalance();
balance += amt;
setBalance(balance);
}
}
abstract class BankAccount {
private int accountNumber;
private double balance;
public BankAccount(double initialDeposit, int accountNumber) {
balance = initialDeposit;
this.accountNumber = accountNumber;
}
public double getBalance() {
return balance;
}
public int getAccountNumber() {
return accountNumber;
}
public boolean withdraw(double amt) {
if (amt > balance) {
return false;
}
balance -= amt;
return true;
}
public void deposit(double amt) {
balance += amt;
}
protected void setBalance(double balance) {
this.balance = balance;
}
}
class CheckingAccount extends BankAccount {
private int checksWritten;
public CheckingAccount(double initialDeposit, int accountNumber) {
super(initialDeposit, accountNumber);
}
protected boolean writeCheck(double amt) {
checksWritten++;
return withdraw(amt);
}
@Override
public String toString() {
return "Checking Account #" + getAccountNumber() + ": " + getBalance();
}
}
class SavingsAccount extends BankAccount {
public SavingsAccount(double amt, int accountNumber) {
super(amt, accountNumber);
}
@Override
public String toString() {
return "Savings Account #" + getAccountNumber() + ": " + getBalance();
}
}
class InvalidAccountTypeException extends Exception {
}
class BankAccountDriver {
public static BankAccount createAccount(String line) throws InvalidAccountTypeException{
String[] params = line.split(",");
if (params[0].equals("S"))
return new SavingsAccount(Double.parseDouble(params[2]), Integer.parseInt(params[1]));
if (params[0].equals("C"))
return new CheckingAccount(Double.parseDouble(params[2]), Integer.parseInt(params[1]));
if (params[0].equals("I"))
return new CompoundInterestAccount(Double.parseDouble(params[2]), Integer.parseInt(params[1]),new GregorianCalendar(Integer.parseInt(params[3]), Integer.parseInt(params[4]), Integer.parseInt(params[5])));
throw new InvalidAccountTypeException();
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("accounts.txt"));
String line;
while ((line = br.readLine())!=null) {
try {
createAccount(line);
} catch (InvalidAccountTypeException ex) {
System.err.println(line + ": INVALID ACCOUT TYPE");
}
}
}
}
Please report if you find any bug!
Also note that since Rate of Interest is not given in the question, so i have considered RoI as 4%
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.