Lab 6 In-Class: Classes and Conditionals

As usual, create a lab6 subdirectory for today's lab, open up Mozilla Firefox and the Web version of this handout, and Eclipse.

  1. Program Student.java contains the incomplete Student class declaration from the prelab.
    1. 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).

    2. Program Grades.java contains a shell program that declares two Student objects. Fill in statements to do the following for each student (use the comments in the code to determine where to put these - this is similar to prelab but not exactly the same):
      • Prompt for and read in the second student's name.
      • Create a Student object using the name you read in and store it in the appropriate Student variable.
      • Prompt for and read in the first student's score on test 1. Use setTestScore to set the test score for the student1 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.
      • Repeat the above for the second student.
      Test your program.

    3. Modify the setTestScore method of the Student class so that it checks for valid grades. BEFORE the code that tests to see which test grade is to be set, check to see if the score is valid. That is, if the score sent in (the formal parameter) is less than 0 print a warning indicating a negative grade is not valid (and set the score to 0 rather than the negative number entered); if a score greater than 100 is entered, a warning message is printed but the score passed in is not changed.

    4. Test your program by entering some grades both inside and outside the 0 - 100 range.

    5. Add an if...else... statement to the Grades program that determines who has the highest average. Your statement should print a message that includes the name of the person with the highest average (use the getName method to do that). Also be sure to check for a tie and print an appropriate message in that case.

    6. Add statements to the end of your Grades program that print the values of your Student variables directly, e.g.:
          System.out.println("Student 1: " + student1);
      
      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 was one in the Account class last week). 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).

    7. Add a toString method to your Student class that returns a string containing the student's name and test scores in the following format:
                        Name: Joe  Test 1: 85  Test 2: 91
      
      Note that the toString method does not call System.out.println -- it just returns a string. Both the Die class (page 165), the Account class (pages 178-179), and the Coin class (pages 221-222) in your textbook have toString methods.

      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!

    8. 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.

    9. Print Student.java and Grades.java.

  2. The file Customer.java contains a class representing a customer of the local Water Authority. The file WaterBill.java contains a program that uses the class to compute a customer's water and sewer bill.

    1. Save the files to your directory then open and study the Customer class. You should note the following:
      • There are three constants defined (these are numbers used in the calculations). It is standard to make constants public (since nobody can change constants anyway) and if the same constants apply to all members of a class to make them static. These constants can be accessed by a client program using the class name and dot operator - for example, Customer.CUTOFF.
      • There are three pieces of instance data that describe a customer: the name, the number of gallons of water used, and whether or not the person is a senior citizen (note that this is represented by a boolean variable that will be true if the customer is a senior citizen and false otherwise).
      • The class has a constructor with three parameters, one for each of the instance variables.
      • The class has an accessor (getter) method for the number of gallons.
      • The class has a method to compute the water bill. This is where most of the work is done. Eventually (after you add code) the water bill will consist of a charge for water usage, a sewer charge, and a utility tax. Currently the only value computed is the charge for water. A separate method is used to do the calculation - that method getWaterCharge is called by the computeWaterBill method. Note that getWaterCharge is a private method. It is a support method for computeWaterBill (see page 170 of the text for a discussion of support methods). Also note that since the method is in the same class it is invoked just with its name (and parameters), not with the "object dot" notation.
      • The getWaterCharge method computes and returns the amount charged for water usage based on the following rule: a customer who uses no more than 7500 gallons in a month pays $0.002 per gallon used but a customer who uses more pays $0.002 per gallon for the first 7500 gallons plus $0.0035 per gallon for each gallon over 7500. Study the if statement to make sure you understand the calculation.

    2. Open WaterBill.java and study it. You should note the following:
      • The program reads in the information (name, number of gallons, and age) for a customer then assigns a value to the boolean variable seniorCitizen based on the age (note that it assigns the variable to be the value of a boolean expression - the value will be true if the age is greater than or equal to 65 otherwise it will be false). The values are then used to instantiate a Customer object.
      • The program then invokes the computeWaterBill method to compute and print the water bill.
      • The program then has an if statement at the bottom that prints a message for customers who use less than half the cutoff amount. Note that the condition uses the getGallons accessor method to get the number of gallons of water used by the customer and it uses the CUTOFF constant that is defined in the Customer class as a static constant (hence it is accessed by the class name).

    3. Run WaterBill.java several times to see how it works.

    4. The Customer class has a method getSewerCharge that currently returns 0 (this is there so the class will compile). Add an if ... else ... statement in the method to compute the sewer charge using the fact that the sewer charge is $0.001 per gallon for customers who use less than 7500 gallons but for customers who use 7500 gallons or more the charge is $7.50 plus $0.003 per gallon for each gallon over 7500 (for example, a person who used 8500 gallons would pay $7.50 plus $3.00). You should declare static constants for the $0.001 and $0.003 constants (up with the other constants). In the getSewerCharge method you should declare a local variable to store the sewer charge and then after your if statement return the value of the variable (replace the statement that returns 0). This method will be very similar to getWaterCharge.

    5. In the computeBill method add a statement that calls the getSewerCharge method and stores the answer in the local variable sewerCharge (note that the variable has already been declared). Also modify the statement that calculates totalBill to add the sewerCharge. Finally add a print statement to print the sewer charges after the one that prints the water charges (note: use the money formatter object - see Section 3.6 pages 130 - 132 for a description of the NumberFormat class.)

    6. Compile and run the program.

    7. Now you need to compute the utility tax. The tax rate is 8.5% of the bill for senior citizens but it is 12% for all others. Note that there is a method getUtilityTax whose job is to compute the tax. The method has a formal parameter total that is the amount the tax is paid on (so the computeBill program will pass totalBill as the actual parameter). As you did in computeSewerCharge add a local variable to store the tax, write an if... else... statement to compute the tax, and then return the tax. Note that the boolean expression for the condition in your if statement is a boolean variable, nothing else.

    8. In computeBill add a statement to call getUtilityTax and store the answer in the local variable utilityTax (which has already been declared). Note that you need to send totalBill as a parameter in your call.

    9. In computeBill add a statement that updates totalBill by adding the utility tax to it (see the comment). Add a statement to print out the utility tax (formatted using the currency formatter object) with the rest of the bill.

    10. Run WaterBill.java. Make sure it works correctly.

    11. Finally, in the main method in WaterBill.java there is currently an if statement that prints a message to customers who conserve water. Add another if statement to print a message to those who use too much water. In particular, add a statement to inform those who use more than 3 times the cutoff that they are subject to a $500 fine if their excessive water usage continues.

    12. After thoroughly testing your program print both Customer.java and WaterBill.java.

  3. Generating Javadoc Javadoc is a tool for creating documentation of Java source code. The Javadoc Document Generator (described in Appendix I of the textbook) generates a web page (HTML code) from the Javadoc comments in the source code. First we'll see what the Javadoc looks like for classes in the Java Class Library. In Firefox,

    Now do the following to generate Javadoc for the Student and Customer classes from today's lab.

    1. In Eclipse, choose Project, then Generate Javadoc.
    2. In the Javadoc generation window, be sure that the Javadoc command field contains /usr/local/jdk1.6.0_01/bin/javadoc. If it doesn't edit it.
    3. In the "select types for which javadoc will be generated" choose Labs, then lab6. Check Student and Customer.
    4. Click on Finish.
    5. Now go to Firefox and choose File, Open File.
    6. In the Open File window, select your Labs directory, then the docs subdirectory. Select the file index.html.
    7. You should see the two classes listed in the left frame of the window.
    8. Click on Customer and scroll down to see what it there. You should recognize the documentation from the class.
    9. Now click on Student. Notice the expanded documentation for the toString method (down at the bottom). The toString you wrote overrides the default toString in the Object class (that's the one that printed something similar to Student@3a56d7).
    10. Print your Javadoc for the Student class.

Hand in: