In an enum it is possible to define a specific behavior for a particular constant of the enum which overrides the default behavior of the enum, this technique is known as constant specific body.
Suppose three piano students - John, Ben and Luke - are defined in an enum named PianoClass, as follows:
enum PianoClass { JOHN, BEN, LUKE; public String getSex() { return "Male"; } public String getLevel() { return "Beginner"; } }
And one day two other students arrive - Rita and Tom - with a sex (Female) and level (Intermediate) that do not match the previous ones:
enum PianoClass2 { JOHN, BEN, LUKE, RITA, TOM; public String getSex() { return "Male"; // issue, Rita is a female } public String getLevel() { return "Beginner"; // issue, Tom is an intermediate student } }
so that simply adding the new students to the constant declaration, as follows, is not correct:
PianoClass2 tom = PianoClass2.TOM; PianoClass2 rita = PianoClass2.RITA; System.out.println(tom.getLevel()); // prints Beginner -> wrong Tom's not a beginner System.out.println(rita.getSex()); // prints Male -> wrong Rita's not a male
It's possible to define a specific behavior for each of the constant, Rita and Tom, which overrides the PianoClass2 default behavior as follows:
enum PianoClass3 { JOHN, BEN, LUKE, RITA { @Override public String getSex() { return "Female"; } }, TOM { @Override public String getLevel() { return "Intermediate"; } }; public String getSex() { return "Male"; } public String getLevel() { return "Beginner"; } }
and now Tom's level and Rita's sex are as they should be:
PianoClass3 tom = PianoClass3.TOM; PianoClass3 rita = PianoClass3.RITA; System.out.println(tom.getLevel()); // prints Intermediate System.out.println(rita.getSex()); // prints Female
Another way to define content specific body is by using constructor, for instance:
enum Friend { MAT("Male"), JOHN("Male"), JANE("Female"); private String gender; Friend(String gender) { this.gender = gender; } public String getGender() { return this.gender; } }
and usage:
Friend mat = Friend.MAT; Friend john = Friend.JOHN; Friend jane = Friend.JANE; System.out.println(mat.getGender()); // Male System.out.println(john.getGender()); // Male System.out.println(jane.getGender()); // Female
Each enum class contains an implicit static method named values(). This method returns an array containing all values of that enum. You can use this method to iterate over the values. It is important to note however that this method returns a new array every time it is called.
public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; /** * Print out all the values in this enum. */ public static void printAllDays() { for(Day day : Day.values()) { System.out.println(day.name()); } } }
If you need a Set you can use EnumSet.allOf(Day.class) as well.
When a method need to accept an "extensible" set of enum values, the programmer can apply polymorphism like on a normal class by creating an interface which will be used anywere where the enums shall be used:
public interface ExtensibleEnum { String name(); }
This way, any enum tagged by (implementing) the interface can be used as a parameter, allowing the programmer to create a variable amount of enums that will be accepted by the method. This can be useful, for example, in APIs where there is a default (unmodifiable) enum and the user of these APIs want to "extend" the enum with more values.
A set of default enum values can be defined as follows:
public enum DefaultValues implements ExtensibleEnum { VALUE_ONE, VALUE_TWO; }
Additional values can then be defined like this:
public enum ExtendedValues implements ExtensibleEnum { VALUE_THREE, VALUE_FOUR; }
Sample which shows how to use the enums - note how printEnum() accepts values from both enum types:
private void printEnum(ExtensibleEnum val) { System.out.println(val.name()); } printEnum(DefaultValues.VALUE_ONE); // VALUE_ONE printEnum(DefaultValues.VALUE_TWO); // VALUE_TWO printEnum(ExtendedValues.VALUE_THREE); // VALUE_THREE printEnum(ExtendedValues.VALUE_FOUR); // VALUE_FOUR
Note : This pattern does not prevent you from redefining enum values, which are already defined in one enum, in another enum. These enum values would be different instances then. Also, it is not possible to use switch-on-enum since all we have is the interface, not the real enum.
Learn All in Tamil © Designed & Developed By Tutor Joes | Privacy Policy | Terms & Conditions