Those of you paying attention should have noticed something pretty important that I said earlier in this chapter in Creating an Enum labthat enums are just Java classes. They have some special behavior that you get for free, but ultimately they are indeed compiled classes. What's important about this is that it implies that you can do some pretty cool things with enums beyond the basics you've seen so farsuch as adding methods to the enum. This is a great way to make your enum even more valuable to application programmers.
Adding methods to an enum works just like adding methods to a normal Java class. Example 3-7 is a beefed-up version of GuitarFeatures that adds several new methods.
package com.oreilly.tiger.ch03; public enum GuitarFeatures { ROSEWOOD(0), // back/sides MAHOGANY(0), // back/sides ZIRICOTE(300), // back/sides SPRUCE(0), // top CEDAR(0), // top AB_ROSETTE(75), // abalone rosette AB_TOP_BORDER(400), // abalone top border IL_DIAMONDS(150), // diamond/square inlay IL_DOTS(0); // dots inlays /** The upcharge for the feature */ private float upcharge; GuitarFeatures(float upcharge) { this.upcharge = upcharge; } public float getUpcharge( ) { return upcharge; } } public String getDescription( ) { switch(this) { case ROSEWOOD: return "Rosewood back and sides"; case MAHOGANY: return "Mahogany back and sides"; case ZIRICOTE: return "Ziricote back and sides"; case SPRUCE: return "Sitka Spruce top"; case CEDAR: return "Wester Red Cedar top"; case AB_ROSETTE: return "Abalone rosette"; case AB_TOP_BORDER: return "Abalone top border"; case IL_DIAMONDS: return "Diamonds and squares fretboard inlay"; case IL_DOTS: return "Small dots fretboard inlay"; default: return "Unknown feature"; } } }
There are quite a few things here that you'll need to take note of. First, the class now has a constructor that takes in a float parameter for the upcharge of each feature. As a result, each enumerated type now passes in a parameter to the constructor:
ROSEWOOD(0), // back/sides MAHOGANY(0), // back/sides ZIRICOTE(300), // back/sides SPRUCE(0), // top CEDAR(0), // top AB_ROSETTE(75), // abalone rosette AB_TOP_BORDER(400), // abalone top border IL_DIAMONDS(150), // diamond/square inlay IL_DOTS(0); // dots inlays
This looks a little odd in the code, but opens up a world of possibilities for information to be passed in for each value. You should also notice that the final value is followed by a semicolon. This denotes the end of the values section, and is required.
Then, variables are declared, and methods appear, just like any other class. In the example, getUpcharge( ) returns the value supplied to the constructor, and getDescription( ) supplies a human-readable version of the feature. You'll see that switch is used, as described in Switching on Enums, and this makes the method body simple to read and understand.
|
...limiting access to the enum constructor? Enum constructors are implicitly private, so this is taken care of for you. In some programming techniques, such as singletons, access modifiers are placed in front of the constructor so that it can't be directly accessed:
public enum GuitarFeatures { ROSEWOOD(0), // back/sides MAHOGANY(0), // back/sides ZIRICOTE(300), // back/sides SPRUCE(0), // top CEDAR(0), // top AB_ROSETTE(75), // abalone rosette AB_TOP_BORDER(400), // abalone top border IL_DIAMONDS(150), // diamond/square inlay IL_DOTS(0); // dots inlays /** The upcharge for the feature */ private float upcharge; private GuitarFeatures(float upcharge) { this.upcharge = upcharge; } // Other method bodies }
This compiles, but it just explicitly does what the compiler takes care of for youmaking the constructor private. However, you cannot supply the standard public modifier:
public GuitarFeatures(float upcharge) { this.upcharge = upcharge; }
If you try this, you'll get a compiler error:
[javac] src\ch03\GuitarFeatures.java:21: modifier public not allowed here [javac] public GuitarFeatures(float upcharge) { [javac] ^
So leave all modifiers off of enum constructors.