Objective of this Program: To learn about using inheritance in Java, with overloaded methods.
This program is inspired by simple programming project in Section 7.1 on pages 503-513 of the text. Look at the code in these listing for some models of what to do. However, since the author covered Academics, I decided to do a similar project with different types of Bank Accounts.
We consider a class diagram of a bank accounts. Each arrow represents an inherited class. We discussed the some of the uses of the student part in class and it is used in the notes about inheritance . of the hand-out. To get a different picture, we will look at 4 different types of bank accounts: basic account, checking account, savings account, and money market account. For extra credit one can consider certificates of deposit (CD).
One can find the UML of each of the four account classes, as well as a ADT of each of the methods of the 4 classes.
The implementation of all of the methods is straightforward. Each constructor first calls super with the inherited members from its parent(s). It then assigns the values to the members which are unique to it.
E.g., Checking would have the line
super(name,balance);
followed by the line:
this.fee= fee;
The other methods are straightforward: get, set, are each of one line. (Be sure in toString to call the super.toString() and append the new output values to it for the Savings. One does not need to and should not reconstruct it from scratch.)
When necessary, the withdraw and deposit have to be modified. You modify them by overriding them. That is to say, one redefines them with the same parameters as their super class. Then when a member of this class is referenced with these methods, the compiler will choose the overridden method. Note that this is different than overloading a method. A method is overloaded when one has another method of the same name in the class, but it has a different set of parameters which are passed to it. E.g., the constructor for Account is overloaded.
You should use the super method as much as possible. E.g., for the class Checking the method of withdraw would subtract the fee from the balance for each withdrawal. However, the withdraw of Account should be called via super.withdraw(amount).
An example of the BankAccount.java can be downloaded as a model for the other classes to be created. This class is complete and does not have to be modified.
To test your accounts with various transactions it will be necessary to create an array of accounts of savings, checking, or MoneyMarket. I have already created a text file of data, which you can get at accounts.txt. The data is stored in ASCII with the first piece of data on each line a key denoting which of the 3 classes it belongs to. It has 3 different key values:
1 Checking 2 Savings 3 MoneyMarketIt is then followed by the account name and the opening balance. For Savings, it is also followed by the interest rate, while for MoneyMarket, it is followed by both the interest rate and the minimum amount for a transaction.
To save you the problem of having to create the array, I have created a class called InputData which has a method of getInputAsAscii whose protocol is
public int getInputAsAscii(File,BankAccount [])
It is passed an object of the File class as well as an array of Accounts. It will read in the data from the File passed to it, rejecting bad data, and return how many elements are in the array.
You can download this class of InputData by clicking here.
Note that you must translate the file accounts.txt into a File class via
File inputFile = new File("accounts.txt");
You can choose which interface you want to test the account classes. The two choices are to either (1) a GUI or (2) the console window.
To start off, you must ask the user for the name of the data file, which in this case will be accounts.txt. However, you want to ask the user for the data. If you are doing a GUI, you could have a JButton which when clicked will ask the user for the data.
Once you have the array of Accounts, what you must test for is as follows:
You ask the user (either by a System.out.print or JButton for either 1 of 6 actions:
deposit withdraw transfer computeInterest print out data of all accounts exit the programFor the first 3, one must have the account and the amount. For the transfer, one needs the account to be transferred to. This can be done via a System.out.print for the console application or a JTextField for the GUI.
You then carry out the transactions. Note that all of the accounts will start at number 1000 and will increase sequentially after that. So account number 1008 is the 9th account in the list. I.e., one does not need to do a search for the account in the list of accounts.
Note: Be sure to use a try...catch for ArrayIndeXOutOfBoundsException in case the user gives too large (or too small) an account number. You must also catch the NullPointerException in case the user gives an index of an account which has not yet been created (although the account number is within the array size).
The integers returned by deposit, withdraw, and transfer should be translated into messages which are displayed. For console interfaces, it should be at the window, for GUI it should be in a JTextArea. The same for the printing of all the accounts.
Note: The console window is easier to implement but the GUI is more fun. If you do the console window, you should offer the user a list of options and use a switch statement depending on the options.
Note:If you do a withdrawal, then the code should just be
int value = account[i].withdraw(amount);
regardless of the type of account. This is the idea of inheritance. Each of the account[i] is of the type Checking, Savings, or MoneyMarket, but it is the compiler which will do the binding. Your code will just be as above.
To perform the action of computeInterest one has to go through the entire array of accounts and compute the interest only for Accounts of type Savings or MoneyMarket. You must first determine whether an account is of type Savings. You do this by
if (account instanceof Savings)
Then to call the method of calculateInterest, you must cast down the account which is of type BankAccount to a class of type Savings. This is because the class BankAccount does not have the method calculateInterest. You do this with the following syntax:
( (Savings) account).calculateInterest();
Notice the syntax. You must cast down within before you invoke the method of calculateInterest. This is why it is enclosed inside the parenthesis.
The entire action can be done in 3 lines of code. (1) A for loop to go through the array of Accounts, (2) an if statement to determine whether it is an instance ofSavings, and (3) the then statement which does the calling of calculateInterest.
Note that you should do this loop using the enhanced for loop without using an index. It is cleaner code. That is the syntax I am using above.
Note:The interest rate given is the yearly interest rate, and one calculates the interest daily in today's environment. So one must compute the interest earned by dividing the interest rate by 365.
The printing out of the data of all accounts if just a for loop. Again, one should do this via an enhanced for loop.
Note: When one exits the program one should
The file containing the modified account information should reside in the same subdirectory as the project. I.e., you should just call it "newaccounts.txt" or some other name. No path names are required. Be sure to close the PrintWriter before exiting the program, as it might not be written to the disk when the program terminates. (This is because of the large size of buffers in RAM and the small size of the data file we are working with.)
Note:The output saved to the file should be the same as the input read in from accounts.txt. That is to say, it should be
You can get this information with the various "get" methods. Be sure to cast the object down to the proper class to get the information. E.g., ((Savings) acc[i]).
The GUI interface should at the beginning just show a button which asks for the input file name:
When one clicks on the button, a message box will appear prompting the user for the input file name:
Then when one gives a correct file name (i.e., a file which can be found and has correct input data), one will see the rest of the interface. An example could be like the example below:
You should be able to do a better interface than this. Note that I have used a combo box for the 3 transactions, deposit, withdraw, or transfer. I could have put the compute interest as one of the types of transactions, and in fact all of the 6 actions (4 transactions and printing the accounts and exiting the program) in the combo box. It is just a matter of taste.
Points will be taken off it you don't modularize your program. How you do this is up to you, but for the GUI, most of the actionPerformed should be function calls. The same with the console window.
The data for the accounts will consists of one account per line. Each line will have three, four, or five pieces of data depending whether it is a checking, savings, or money market: the key (1 for checking, 2 for savings, and 3 for money market), the name and initial balance. Savings will have the interest rate, while the money market will have the interest rate and the minimal amount for each transaction.
A test accounts.txt file is available for testing.
One can implement the Certificate of Deposit or CD. The CD is like a savings account, except there is a time unit for which it must be kept at the lending institution. This is measured in months, which is stored as an int. If a withdrawal is done before the allotted time, then a penalty is imposed. Also, no deposits are allowed during the time period as well.
The penalty we will impose is that if the CD is for a duration of 6 months or less, one pays a penalty of 90 days of interest. If the duration is more than 6 months, one pays a penalty of 180 days of interest. (I took these from a website of my bank.)
So you must have the start date of the CD as part of its constructor. To simplify matters, we can assume that all CD's start at the first of the month, so one only needs the month and year that it started. One will need a member of the Calendar class to compute the current date and compare it with the start date. I suggest you use the GregorianCalendar class, which is an extension of the Calendar class.
Note that the constructor of CD creates the new GregorianCalendar.
calendar = new GregorianCalendar();
This is needed to compute the whether enough time has passed for the withdrawal.
One must get the current year:
int year = calendar.get(calendar.YEAR);
and month
int month = calendar.get(calendar.MONTH);
and compare them with the start time and the length of the CD.
The data set to test is accountsExtra.txt. You will also need a different input class of InputDataExtra.java for the input of the CD class.
Note:Remember that transfer can not be made into a CD during its time period when it is "closed", as it can not do a deposit. This also means that you must "add" the money back to the account doing the transfer.
You should post your project as a 'zip' file on the COL website. It should be posted under the appropriate assignment. Also indicate how many hours you worked on the program in the Readme.txt file.
Homepage of CTI School
back to 211
homepage