Lab 9 In-Class:
Writing Classes
Lab Objectives
- Gain experience writing a class and using the class in a client
program.
|
Log onto the Linux system and create a lab9 subdirectory of
your cs120/Labs
directory for today's work. As usual, you will need to have three
windows open:
an xterm, Eclipse, and Firefox.
Writing Classes: The Account Class
Program Account.java contains the
Account class from the pre-lab and pages 193-194 from the textbook.
- In the Account class (Account.java) do the following:
- Fill in the declaration/initialization of the constant for the
$10.00 fee (after the RATE constant - below the comment).
- Modify the deposit method so that if the amount is negative an
error message is printed; otherwise the amount is added to the balance.
- Modify the withdraw method to check for errors. In particular if
the amount is negative print an error message, if the amount is
more than the balance print an "Insufficient Funds" message. Otherwise
subtract the amount from the balance.
- Fill in your definitions for methods chargeFee and
setName.
Make sure your class has no compile-time errors (no red x's).
- Program ManageAccounts.java contains
the shell of the program from the prelab that uses the Account class to
create and manipulate bank accounts using methods from the Account class.
Add code as indicated by the comments.
Note that this program asks you to use getBalance
to print the balance in two places that were not in the prelab and it
has added some interactive input (and asks you to add statements to
deposit and withdraw amounts entered).
Run your program and make sure it works.
- Updating the documentation: It is very important that methods
in a class be well documented so that programmers understand what they
do and can use them properly. Every method should have documentation
just before the method that describes what the method does, the
parameters the method takes, and any values the method returns.
Eclipse will automatically generate javadoc style documentation for
methods. It produces a list of parameters and an @return statement. The
programmer must fill in the following:
- the purpose of the method (must be above the parameter list)
- a description of
each parameter
- a description of what the method returns.
Read through the Account class and you will see that the constructor, the
deposit, addInterest, and chargeFee methods
already have documentation.
Do the following to document the withdraw method:
- Place your cursor on the header for the withdraw method (anywhere
on the header but be sure to be on the code). Then, from the menu,
select Source, Generate Element Comment.
- Eclipse should have generated javadoc comments that look as follows:
/**
* @param amount
* @return
*/
- Add a line describing what the withdraw method does just above
the @param tag (see the deposit documentation). Press enter so you have
a blank line in the documentation between the description and the @param
line.
- Beside the parameter amount (or on the next line -
formatting will put this on the next line no matter where you put it) write
a brief description of the role of the parameter amount (again, see
deposit).
- Beside @return write a description of what is returned by the method.
- Press SHIFT-CTRL-F to format.
- Repeat the above steps to add documentation to getBalance and setName.
You can use the
descriptions in the textbook if you wish (or in pre-lab).
- Although chargeFee returns the new balance, your ManageAccounts program
currently throws that value away. Modify ManageAccounts so that each time it
calls chargeFee it stores the returned balance in a variable (you'll have
to declare a new one). After each call to chargeFee, add a print statement
that prints the stored value of the new balance (appropriately labeled).
- Real bank accounts have many more attributes than the three
in this simple Account class. For example, a record of each transaction
would be associated with each account. That is too complicated for us
but we can keep track of the number of transactions. To do this add
the following to the Account class:
- Add an instance variable named numTransactions of type int.
Remember that we make instance variables private.
- In the constructor, initialize numTransactions to 0. (NOTE: Java
automatically initializes instance variables to 0 but it is generally
a good idea to explicitly assign initial values.)
- In the deposit and withdraw methods increment numTransactions. Note
that this should be done only when the transaction actually occurs, not
when there is an error (such as a negative amount or insufficient funds).
- In the toString method modify the string returned to include
the number of transactions, appropriately labeled.
- Classes often have accessor methods for each attribute
(see page 183-184 of the text). These methods are often called
"get" methods or "getters." All they do is return the value of the
attribute so the client program can use it in some way (print it
or use it in a calculation for example).
The getBalance method is an example
of an accessor method. We need to add a getTransactions
accessor method to the
Account class (note this goes in Account.java). It will be similar
to getBalance except it will return the number of transactions.
Think about what the return type for the method needs to be.
Be sure to generate javadoc comments for the method.
- Add a print statement at the end of the ManageAccounts
program to print out the number of transactions for each account
(use your accessor method). NOTE: Add this even though you are already
printing the complete account information - this time you should
print just the number of transactions using getTransactions.
- You should have noticed that accessor (getter) methods are
very straightforward to write. In fact, Eclipse can automatically
generate both accessor methods (getters) and mutator methods (setters).
An example of a setter is setName - it sets the name attribute
to the new name that is passed in as a parameter.
Have Eclipse generate an accessor method getName()
as follows:
- From the menu, choose Source, Generate Getters and Setters.
- Explore this window by clicking on the small arrow beside
acctNumber - you will see options of a getAcctNumber and a setAcctNumber.
If you click on balance you will only see the option of a setBalance
because the class already has a getBalance. Similarly if you click
on name you will only see the option of getName.
- getName is the one we want so click on the box to select it.
- Now click okay.
- You should see the complete code for the method plus the javadoc.
Add a line describing the method to the javadoc and add a description
of what is returned to the @return
statement.
- Modify the last print statements (that printed the number of
transactions) to also print the name of the account
owner using the getName method in your print statement.
- Run your program to test it then print
Account.java and ManageAccounts.java.
Writing Classes: A Student Class
Program Student.java contains the
incomplete Student class declaration from the prelab.
- Complete the class declaration. You will need to do the
following:
- Declare the
instance data (name, score for test1, and score for test2).
Remember that these should be private.
- Add the bodies for the constructor and the setTestScore method.
- Add the headers and bodies for the getName, averageScore,
highestScore, and letterGrade methods.
Make sure your Student class has no compilation errors (red x's).
- Program Grades.java contains a shell
of a program that contains a sentinel controlled loop (stops when
the name read in is "q") that reads in
the name and two test scores for each student
a class and, for each student, prints the average grade,
the corresponding letter grade, and the highest grade. It will also
compute and print the class average (the average of the student
test averages). All of this will be done using
a Student object and methods from the student class. Fill in statements
in Grades.java to do the following for each student (use the comments in the
code to determine where to put these - note that some of what you need to
do is similar to what you did in pre-lab).
- Declare and initialize any variables needed to compute the class
average (the average of the students' test averages).
- Instantiate a Student object using the name you read in.
- Prompt for and read in the first student's score on test 1.
Use setTestScore to set the test score for the student object.
Repeat this for the score on the second test.
- Use the averageScore
method to find the student's test average and the letterGrade method
to find the corresponding letter grade.
Print this average and letter grade
with a simple label including the name, e.g.,
"Susie's Average is 87.5 which is a B". Use the getName method for the name.
- Use the highestScore method to find and print the student's
highest test score.
- Update the variables for computing the class average.
- Add code to update the loop control variable name - that is, prompt
for and read in the next name (or q to quit).
- After the loop print out the class average, appropriately labeled.
Test your program.
- Add code to the Grades program to determine who
has the highest average and who has the lowest. Notice that there
are already two Student objects (topStudent and bottomStudent) declared
for this. One (topStudent) has been instantiated with an empty name.
You need to do the following:
- Instantiate bottomStudent as a Student object with an empty name.
- Declare variables to keep track of the highest and lowest average
and initialize them appropriately before the while loop.
- Inside the loop update the variables for highest and lowest
average AND keep track of which student currently has the highest and lowest.
For example if the current student has a higher average than the
highest so far assign topStudent to be this student (and of course
update the highest average). The same idea applies for the lowest.
- Add statements to the end of
your Grades program that print the values of your
topStudent and bottomStudent variables directly, e.g.:
System.out.println("The student with the highest average is: " + topStudent);
This should run, but notice what it does -- nothing
very useful! When an object is printed, Java looks for a toString
method for that object. This method must have no parameters and must return
a string (there is one in the Account class).
If such a method exists for this object, it is
called automatically -- you don't have to write the call in your program --
and the string it returns
is printed. If no such method exists, a unique hexadecimal
identifier for the object
is printed (e.g., Student@3a56d7).
- Add a toString method to your Student class (in Student.java)
that returns a string
containing the student's name and test scores in the following format:
Joe Test 1: 85 Test 2: 91
Note that the toString method does not call System.out.println -- it just
returns a string. The Die class, the Account class, and the Coin class
in your textbook all have toString methods. The header is the same for
all - the only difference is in the string returned.
You shouldn't have to
change the Grades program -- you don't have to call toString explicitly.
Now see what happens when you run the Grades program - the output is
much nicer!
- Use Eclipse to generate documentation for the toString method
(recall - you put your cursor on the method header then choose Source,
Generate Element Comment). Edit the non-javadoc comment that was
automatically added by:
- Adding an extra * to make it a javadoc comment.
- Replacing the (non-javadoc) with a description of what
toString does.
- Print Student.java and Grades.java.
Hand In
- The four files (Accounts.java, ManageAccounts.java, Student.java,
and Grades.java).
- Tar your directory and email the tar file
to your instructor with the
subject cpsc120 lab9.