Java version 5.0 introduces many dramatic new language features. This
article further discusses the new enum
facility, demonstrating how you
can define enum constants polymorphically. You may want to first read
the article Typesafe Enum: Using enum in J2SE
5.0.
The Grade enum
In my first article on enum, I introduced a Grade enum. Here is the code:
enum Grade {
A("great"),
B("good"),
C("ok"),
D("eh"),
F("loser");
private String message;
Grade(String message) {
this.message = message;
}
String getMessage() {
return message;
}
}
Suppose you want the ability to determine whether a test score falls into a specific grade. A score of 90 up through 100 is an A; an 80 up to but not including 90 is a B, and so on. A score of less than (but not including) 60 warrants an F.
You can modify the Grade enum to take a lower and upper range for each
grade. You can then provide a method (includes
) to determine whether
or not a score maps to the current Grade enum:
public enum Grade {
A("great", 90.0, 100.0),
B("good", 80.0, 90.0),
C("ok", 70.0, 80.0),
D("eh", 60.0, 70.0),
F("loser", 0.0, 60.0);
private String message;
private double from;
private double to;
Grade(String message, double from, double to) {
this.message = message;
this.from = from;
this.to = to;
}
String getMessage() {
return message;
}
boolean includes(double score) {
return from <= score && score < to;
}
}
So far, nothing new. The only problem is that it won't work. The to
value represents the top end of the grade range and must be
exclusive–except for an A. A perfect score of 100 must report back as
an A, but it does not with the above code.
One solution would be to include special logic in the definition of enum, or perhaps modify the constructor to take a boolean representing whether or not the range upper bound is inclusive.
Another solution is to have the declaration of the Grade.A enum constant
override the definition for includes
.
public enum Grade {
A("great", 90.0, 100.0) {
boolean includes(double score) {
return super.includes(score) || score == to;
}
},
B("good", 80.0, 90.0),
C("ok", 70.0, 80.0),
D("eh", 60.0, 70.0),
F("loser", 0.0, 60.0);
private String message;
private double from;
protected double to;
Grade(String message, double from, double to) {
this.message = message;
this.from = from;
this.to = to;
}
String getMessage() {
return message;
}
boolean includes(double score) {
return from <= score && score < to;
}
}
You supply the new definition for includes
inline, just as if you were
overriding a method in an inner class declaration.
Note that you must also define the to
variable as protected
in order
for this to work.
If you want a different implementation for an enum method for each and
every enum constant, you can declare both the method and the enum type
as abstract
.
Comments
Pingback: Langr Software Solutions » Typesafe Enum: Using enum in J2SE 5.0