Lab 7: Enumerated Types¶
Instructions
Answer the following questions one at a time. After answering each question, check your answer before proceeding to the next question.
Save the following file in your lib/ folder:
Save the following files in src/labs/lab07:
Acknowledgment
This lab was written by Prof. David Bernstein. The original version is here.
Background Material¶
For this lab, you are going to be working with Air Quality Indexes as they are defined by the U.S. Environmental Protection Agency (EPA). You don't need to know much about them, other than the information that is summarized in the following table.
| Category | Min | Max | Description | Color (R, G, B) |
|---|---|---|---|---|
| GOOD | 0 | 50 | Good | Green (0, 228, 0) |
| MODERATE | 51 | 100 | Moderate | Yellow (255, 255, 0) |
| SENSITIVE | 101 | 150 | Unhealthy for Sensitive Groups | Orange (255, 126, 0) |
| UNHEALTHY | 151 | 200 | Unhealthy | Red (255, 0, 0) |
| VERY_UNHEALTHY | 201 | 300 | Very Unhealthy | Purple (153, 0, 76) |
| HAZARDOUS | 301 | 500 | Hazardous | Maroon (126, 0, 35) |
Motivation and Review¶
To motivate the need for enumerated types, in this part of the lab you are going to construct a small application that makes use of the Announcement class to display air quality information.
-
Briefly review
ShowAQI.java. -
Based on your review of
ShowAQI, what is required to execute it "properly"?Answer
It needs to be given a command-line parameter.
-
Execute
ShowAQIusing what you know is required to execute it "properly". What happened?Answer
A window like the following appeared.

How to run
ShowAQIwith a command-line parameter?Step 1: Open
src/labs/lab07/ShowAQI.javain VS Code and press F5 to run the program. This will launch a Terminal window. In the Terminal output, you will see two sections: The command executed to runShowAQI, and the program output, which displays:Usage: java ShowAQI aqi.Step 2: Press the Up arrow key on your keyboard to recall the previous command used to run
ShowAQI. Then, add a space followed by the desired command-line argument. Finally, press Enter to execute the command.An easier way to run
ShowAQIwithout pressing F5Alternatively, you can type the command yourself (without any extra junk from VS Code):
OS Command Linux / macOS java -cp "bin:lib/*" labs.lab07.ShowAQI 50Windows java -cp "bin;lib\*" labs.lab07.ShowAQI 50Explanation:
javais the command for running a Java application-cpstands for classpath, which tells Java where to find.classand.jarfileslabs.lab07.ShowAQIis the fully-qualified name (including package) of the main class to run50(or any other number) is the command-line argument passed to theargsparameter ofmain()
-
Review the source code for
ShowAQI. Why did the window have the color and text that it did?Answer
Because the
findColor()method always returns yellow, and thefindDescription()method always returns "Moderate". -
Why are the
findColor()andfindDescription()methods static?Answer
Because they are going to be called from a static context, specifically the
main()method. Sincemain()is static (and will be called without reference to aShowAQIobject), every method/attribute in theShowAQIclass thatmain()calls/uses must also be static. -
Why don't they need to be called as
ShowAQI.findColor()andShowAQI.findDescription()?Answer
Because they, and
main(), are all in theShowAQIclass. -
Modify the
findColor()method so that it returns the appropriateColorobject. To save time, only consider the first three categories, and treat SENSITIVE as the default. (Don't be fancy – just use nestedifstatements or aswitchstatement and hard-code the ranges.)Answer
private static Color findColor(int aqi) { Color result; if ((aqi >= 0) && (aqi <= 50)) { result = new Color(0, 228, 0); } else if ((aqi >= 51) && (aqi <= 100)) { result = new Color(255, 255, 0); } else { result = new Color(255, 126, 0); } return result; } -
Modify the
findDescription()method so that it returns the appropriateStringobject. Again, to save time, only consider the first three categories, treatSENSITIVEas the default, and don't be fancy.Answer
private static String findDescription(int aqi) { String result; if ((aqi >= 0) && (aqi <= 50)) { result = "Good"; } else if ((aqi >= 51) && (aqi <= 100)) { result = "Moderate"; } else { result = "Unhealthy for Sensitive Groups"; } return result; } -
If you were a system tester (not a unit tester) who had been tasked with building a complete system test suite, what information would you use to identify important test cases?
Answer
The table that was included in the background material.
-
Would this be black-box or white-box testing?
Answer
It would be black-box testing because the tester would not have access to the source code.
-
Conduct a few system tests to see if your application is working. Don't be comprehensive.
-
The design of the
ShowAQIapplication is not very good. For one thing, theShowAQIclass is not cohesive (i.e., it does too many different kinds of things). For another, the implementations offindColor()andfindDescription()contain duplicate code. How can these two problems be solved?Answer
The second problem can be solved by creating a class named
AirQualitythat contains both aColorand aString(as well as theintAQI). That way, one method could "find" and return both at the same time.The first problem can be solved by moving the "find" functionality to the
AirQualityclass. This would make theShowAQIclass much more cohesive. -
In the "real world", how many different
AirQualityobjects are there?Answer
Six, one for each category in the table above.
-
Given your answer to the previous question, should
AirQualitybe aclassor anenum? In other words, do we need an intensive definition or an extensive definition of the set ofAirQualityobjects?Answer
Since there are only six possible
AirQualityobjects, the right thing to do is just list them all (i.e., use an extensive definition). In other words,AirQualityshould be anenum.
An Initial Encapsulation¶
This part of the lab will get you started designing and implementing enumerated types.
-
Review the
AirQualityenum. How many differentAirQualityobjects are there?Answer
As expected, six.
-
Why is the constructor private?
Answer
So that "nobody else" can create an
AirQualityobject (since, after all, there can only be six). -
How many different attributes does each
AirQualityobject have?Answer
Four: a description, a color, a minimum AQI value, and a maximum AQI value.
-
Add accessors for the color and description.
Answer
/** * Get the color associated with this AirQuality object. * * @return The Color */ public Color getColor() { return color; } /** * Get the description associated with this AirQuality object. * * @return The description */ public String getDescription() { return description; } -
Add a
boolean contains(int aqi)method toAirQualitythat returnstrueifaqiis in the interval [min,max] andfalseotherwise. Do not use anifstatement, aswitchstatement, ternary operator, or local variables!Answer
/** * Determine whether a given AQI is within the range of this AirQuality object. * * @return true if the AQI is in [min, max]; false otherwise */ public boolean contains(int aqi) { return ((aqi >= min) && (aqi <= max)); } -
Replace the
Color findColor(int aqi)andString findDescription(int aqi)methods in theShowAQIclass with aAirQuality findAirQuality(int aqi)method. Again, limit your implementation to the first three categories. However, this time, don't use hard-coded ranges. Instead, use thecontains()method in theAirQualityenum.Answer
/** * Find the AirQuality object associated with a particular * air quality index (AQI). * * @param aqi The air quality index * @return The associated AirQuality */ private static AirQuality findAirQuality(int aqi) { AirQuality result; if (AirQuality.GOOD.contains(aqi)) { result = AirQuality.GOOD; } else if (AirQuality.MODERATE.contains(aqi)) { result = AirQuality.MODERATE; } else { result = AirQuality.SENSITIVE; } return result; } -
Modify the
main()method of theShowAQIclass so that it uses thefindAirQuality()method.Answer
/** * The entry-point of the application. * * @param args The command-line arguments */ public static void main(String[] args) { AirQuality quality; Announcement announcement; int aqi; if ((args == null) || (args.length < 1)) { System.out.println("\nUsage: java ShowAQI aqi\n"); } else { aqi = Integer.parseInt(args[0]); quality = findAirQuality(aqi); if (quality == null) { System.out.println("\nInvalid AQI. Please try again.\n"); } else { announcement = new Announcement(quality.getDescription(), quality.getColor()); announcement.setVisible(true); } } } -
Test the modified
ShowAQI. -
Is
ShowAQIcohesive?Answer
Not yet.
An Improved Encapsulation¶
This part of the lab will help you understand why and how to build functionality into enumerated types.
-
Move the
findAirQuality()method from theShowAQIclass to theAirQualityenum. (Note: You will have to change the visibility topublic.) -
Why is the
findAirQuality()method static?Answer
Because it is going to be used to find an
AirQualityobject. If it weren't static, we would need anAirQualityobject before we could call it. -
Modify the
ShowAQIclass so that it uses thefindAirQuality()method in theAirQualityclass.Answer
quality = AirQuality.findAirQuality(aqi); -
Why do you now need to include the class name in the call to the method?
Answer
Because
findAirQuality()is in theAirQualityclass and this statement is in theShowAQIclass. -
Test the modified
ShowAQI. -
Is the
ShowAQIclass cohesive?Answer
Yes. It now does one thing – it shows air quality information.
-
Is the
findAirQuality()method in theAirQualityclass complete?Answer
No, it only works for three of the six
AirQualityobjects. -
Given that there are only six different
AirQualityobjects, how long would it take to add the other three cases?Answer
A minute or two.
-
Suppose there were 100 different
AirQualityobjects, how long would it take to add the other 97 cases?Answer
It would take some time, and it would be annoying.
-
Suppose an
AirQualityneed to be added to theenumthree years from now. How likely is it that you will remember to also modify thefindAirQuality()method?Answer
Very unlikely!
-
Use the
values()method and a traditionalforloop to fully-implement thefindAirQuality()method. (Returnnullif the if theaqiis out of bounds.)Answer
/** * Find the AirQuality object associated with a particular * air quality index (AQI). * * @param aqi The air quality index * @return The associated AirQuality */ public static AirQuality findAirQuality(int aqi) { AirQuality[] all; all = AirQuality.values(); for (int i=0; i<all.length; i++) { if (all[i].contains(aqi)) { return all[i]; } } return null; } -
Test the modified
ShowAQI.
Submission¶
- Submit only
AirQuality.javaandShowAQI.javato Gradescope. - Answer the questions in Canvas for your section's Lab 7 assignment based on this lab.