This exercise is designed to give you more practice developing a class from specifications. It will also give you a chance to write an informal tester program that will read numeric input from the keyboard, as well as practice using some of the String methods.
While the metric system is handy because everything is in terms of units of 10's, the English (or Imperial) System for weight can be somewhat difficult to work with, because there are 16 ounces in one pound. In the exercise this week, we'll try to overcome some of those problems by developing a class to keep track of an English weight and provide some methods to help make calculations easier.
The class you will develop is named EnglishWeight, which will keep track of the whole number of pounds and the whole number of ounces. The EnglishWeight class is helpful in that it can be created from a String value given to the constructor. You can assume that the String will always be in the format "X pounds and Y ounces" where X and Y are each a whole number greater than or equal to 0. You can also assume that the number of ounces will be less than 16. You'll then provide information about these values and even do a few computations. Specifically, it can provide:
Be sure to read through all items before you begin. You will notice that these steps encourage the process known as incremental development'. That is, write just a little bit of code and test it. Only once you get correct results do you move on to the next item.
HINT: You might find it useful to print a hard copy of this document and cross out the items as you complete them
1. Create a new Java project named YourLastNameLab04
2. Add a new package named edu.westga.cs6311.weights.controller with three classes (each with their own appropriate Javadoc comments):
3. Create a second package named edu.westga.cs6311.weights.model that contains a class called EnglishWeight. This class will not define main, but should have appropriate Javadoc comments.
4. Consider the EnglishWeight class specifications and determine the variable(s) that are necessary to perform the tasks in this class. As a hint, consider what things you would need to completely describe an EnglishWeight object (according to the Problem Statement).
5. Write the Javadoc specification comments for the EnglishWeight constructor. Recall that the purpose of the constructor is to initialize the instance variable(s). Be sure to reread the Problem Statement and think about what the constructor will need to accept in order to complete this task. Once the comments are written, write the Java code for this constructor.
6. Java convention says that when you write a class, you should also include a method with the signature (we'll learn why later in the curriculum):
public String toString()
This method will return a String representation of the object. Typically, this means that you'll return a String value that includes the values of the instance variables. To keep things simple, have this String always be in the format: "X lbs, Y oz", where X is the number of pounds and Y is the number of ounces.
Include the Javadoc comments and Java code for this method in your EnglishWeight class.
7. Once you feel that these methods are correct, go to the WeightDemo class and define
8. Now it's time to turn to the driver's code. Go to the WeightDriver class' main method and include code to create a WeightDemo object and use that object to call the testSingleWeight method.
9. Run the program and confirm that the output is correct. If it is not, go back and fix the code so that it is.
10. So far our EnglishWeight class doesn't do much (OK, it doesn't really do anything yet). Let's turn our attention to the EnglishWeight's getPounds() method.
Write the Javadoc specification comments and Java code for the accessor (getter) method:
public int getPounds()
11. Let's test this code out by revisiting the WeightDemo class. Inside the testSingleWeight method, include the code to print:
12. Run the program and confirm that the output is correct. If not, go back and fix the code so that it is.
13. Repeat this same process that you just did for the pounds, but this time include code for the number of ounces.
14. Once you have a getPounds() and a getOunces(), follow the same process that will compute and return the total number of ounces stored.
15. The EnglishWeight code now works correctly for our informal test, let's turn our attention to interacting with the user - we'll let them enter some values to create an EnglishWeight and then work with that object.
Go to the InteractiveWeightDemo class. Because we'll be getting input values from the user, we'll need an instance variable for the Scanner object.
16. Write a 0parameter constructor to initialize the Scanner instance variable.
17. Our InteractiveWeightDemo class will need a method called runWeight. This method should accept no parameters and have no return value. Inside the method body, write code to:
Note: there's no way you can print out an 'expected' value because you don't know what values will be entered by the user!
18. Finally, return to the driver class and inside main create an instance of InteractiveWeightDemo and then use that object to call the runWeight method. Try running the application (multiple times): enter some values, and check the output to confirm that the results are correct. Fix any errors that you detect.
Although it is not required to look this way, output from your application might look something like: see image.
19. Next we'll turn our attention to adding two different EnglishWeight objects. For this we'll go to the EnglishWeight class and start off our getSum method. Note that this method will need to be passed another EnglishWeight object in order to do its work. And because it is getting a sum of the weights, this method will need to return an EnglishWeight object. This means that this method header will be:
public EnglishWeight getSum(EnglishWeight anotherWeight)
Write the method body here so that it returns a new EnglishWeight object that would be result from adding the two EnglishWeight's together. Hint: you should make use of the existing methods available inside the EnglishWeight class, as well as math operators, including %. Also know that you are not allowed to use any type of decision structure for this exercise (we haven't covered them yet!)
20. Go back to the WeightDemo class and write a new method testTwoWeights. This method will:
21. Modify the code inside the WeightDriver so that testTwoWeights is called after testSingleWeight.
22. Now we can go back to the InteractiveWeightDemo class and get the user to input information for a second EnglishWeight, then use these objects display the sum by calling getSum.
So now the output might look like: see image.
23. Finish out the EnglishWeight class by writing and testing the following methods:
getLighterWeight(EnglishWeight anotherWeight)
Hint: Use the Math.min method to help here
getHeavierWeight(EnglishWeight anotherWeight)
Hint: Use the Math.max method to help here
Be sure to follow the steps we've been teaching here. That is, write the code inside of EnglishWeight, then visit WeightDemo to write code to display expected and actual values, then go to InteractiveWeightDemo and add the code to show the results of this method (that we have now confirmed will work correctly).
Important:
Although it might seem more obvious to use some kind of selection structure for the last two methods, we have not covered this yet in our course, therefore I will ask that you please not use this. Instead, just use the Math class methods to help us out for now.