Java Enumerations: Attaching Methods to Enumerations

Java
Enumerations: Attaching Methods to Enumerations

Suppose
we want to convert a user-specified weight in pounds to a different unit of
measure, such as kilograms, carats, or ounces.

·To convert pounds into
kilograms, for example, we would multiply the given value by the constant
0.45359237.

·To convert pounds into
carats, we would multiply the given value by the constant 2267.96185.

Thus,
we could be tempted to declare the following type of enumeration:

enum
Converter {

0.45359237, 2267.96185,
453.59237, 16, ..., ...

}

Now,
we will need to remember that:

·the first conversion factor
converts the given pounds into kilograms

·the second converts it into
carats,

·the third converts it into
grams

·and so on….

In
the future, if we change this order or insert one more conversion factor
between two existing ones, we cannot be assured that the conversions performed
in the client application will be accurate for all measurement units. We can
easily overcome this problem by using the class features of the enum declaration. For each constant, we
define a conversion method. To understand how this is done, refer to the
complete conversion utility given here:

public class
UnitsConverter {

private static double
numberToConvert = 0;

public static void
main(String[] args) {

if (args.length == 0) {

System.out.println("Usage:
java UnitsConverter <weight in pounds>");

System.exit(0);

}

numberToConvert =
Double.parseDouble(args[0]);

System.out.println("lbs
" + args[0] + " equals:\n");

for (Converter
conv : Converter.values()) {

System.out.printf("%s:
%f%n", conv,

conv.performConversion(numberToConvert));

}

}

}

enum Converter {

KG("KG") {

double
performConversion(double f) {

return f
*= 0.45359237;

}

},

CARAT("carat")
{

double
performConversion(double f) {

return f
*= 2267.96185;

}

},

GMS("gms") {

double
performConversion(double f) {

return f
*= 453.59237;

}

},

OUNCE("ounce")
{

double
performConversion(double f) {

return f
*= 16;

}

},

STONE("stone")
{

double
performConversion(double f) {

return f
*= 0.071428571429;

}

};

private final String
symbol;

Converter(String symbol)
{

this.symbol =
symbol;

}

@Override

public String toString()
{

return symbol;

}

abstract double
performConversion(double f);

}

In
this code, we declare an enumeration called Converter. We also define an abstract method called performConversion,
as follows:

abstract double
performConversion(double f);

Each
constant defined in the Converter will now have to implement this method. Look
at the KG declaration, shown here:

KG("KG")
{

double
performConversion(double f) {

return f *= 0.45359237;

}

},

The
declaration implements the performConversion method, which
multiplies the input number by a predefined constant. This constant value is
the same as the one specified earlier to convert pounds into kilograms. The
name of the constant is KG. Its instance is created by calling the constructor
as follows:

KG
("KG")

The
constructor takes a string argument that will be used in printing the name or
the description of the respective constant. For this, we define a private
constructor, as in the earlier case, that copies the input parameter
into an instance variable. We also override the toString method, as in
the earlier case, to return the appropriate name to the caller.

Likewise,
we add the definitions of other conversions such as CARAT, GMS, OUNCE, and so on.
In the main function, we simply iterate through all the elements of this
Converter enumeration to print the conversions of a given value to different
units. Typical program output is shown here:

lbs 5.0 equals:

KG: 2.267962

carat: 11339.809250

gms: 2267.961850

ounce: 80.000000

stone: 0.357143

In
the future, if we want to add more conversion units, we can do so easily by
adding a new constant definition anywhere we want. For example, to add a troy ounce
conversion after the ounce conversion, we add the following constant
declaration between the ounce and stone declarations:

TROYOUNCE("troy
ounce") {

double
performConversion(double f) {

return f
*= 14.583333333;

}

},

When
we run the client program after this new addition is done, in the output we
will see the given pounds converted into troy ounce.

Whenever
we add a new constant in the Converter enumeration, we need to provide the
implementation of the performConversion method because
this method has been declared an abstract method in the Converter enumeration.
This makes the enumeration definition foolproof.