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 (Tiger).
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.