Lab 6 In-Class: Conditionals and More Classes

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

  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 inputGrades method.
      • Add the headers and bodies for the getName, getAverage, highestScore, and letterGrade methods.
      Compile your Student class.

    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):
      • Prompt for and read in the student's name.
      • Create a Student object using the name you read in and store it in the appropriate Student variable.
      • Use the inputGrades method to read in the student's test scores.
      • Use the getAverage 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.
      Test your program.

    3. Modify the inputGrades method of the Student class so that it checks for valid grades. That is, if a grade entered is less than 0 it prints a warning indicating a negative grade is not valid (and it sets the grade to 0 rather than the negative number entered); if a grade greater than 100 is entered, a warning message is printed and the grade is set to 0. This should be repeated for each grade entered.

    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 compile and 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. 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 that returns a string containing the student's name and test scores, e.g.:

                        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.

      Recompile your Student class and the Grades program (you shouldn't have to change the Grades program -- you don't have to call toString explicitly). Now see what happens when you print a student object -- much nicer!

    7. 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 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).
      • 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. Compile WaterBill.java (which will also compile Customer.java) and run the program 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 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 the 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. Compile and 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.

Hand in: