|
Class-Enum Hybrids
An Introduction with Examples in Java |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
Color class
contains instances like Color.RED,
Color.GREEN, ...)Color class that includes
an instance that couldn't be represented by the color model
being used; an upper/lower bound on an ordered set that is
not an element of the set)
Temperature objects for equipment that
can be used for heating and/or coolingpublic:
final:
static:
== (though can
be compared with the equals() method)equals()
methodequals()
method/**
* An encapsulation of a very simple immutable Temperature class/enum
* hybrid.
*
* Note: For simplicity, Temperature objects do not have an associated
* scale (e.g., Farenheit, Celsius/Centigrade, or Kelvin).
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class Temperature
{
private double value;
private String stringValue;
public static final Temperature OFF = new Temperature();
/**
* Construct a Temperature object with a stringValue of "Off"
*/
private Temperature()
{
stringValue = "Off ";
}
/**
* Explicit Value Constructor.
*
* @param value The value of this Temperature
*/
public Temperature(double value)
{
this.value = value;
// Since objects in this class are immutable, it makes sense to
// create the String representation now
stringValue = String.format("%-6.1f", this.value);
}
/**
* Return true if and only if this Temperature objects
* has the same value as the given Temperature object.
*
* @param other The Temperature of interest
*/
public boolean equals(Temperature other)
{
return stringValue.equals(other.stringValue);
}
/**
* Return a String representation of this Temperature
*
* @return The String representation
*/
public String toString()
{
return stringValue;
}
}
equals() Method Revisited
public boolean equals(Temperature other)
{
if ((other == OFF) && (this == OFF)) return true;
else if ((other == OFF) && (this != OFF)) return false;
else if ((other != OFF) && (this == OFF)) return false;
else return stringValue.equals(other.stringValue);
}
enum
Month Enum as a Class/**
* A class (rather than an enum) for the months of the year.
*
* @author Prof. David Bernstein, James Madison University
*/
public class Month
{
public static final Month JANUARY = new Month("January", 31);
public static final Month FEBRUARY = new Month("February", 28);
public static final Month MARCH = new Month("March", 31);
public static final Month APRIL = new Month("April", 30);
public static final Month MAY = new Month("May", 31);
public static final Month JUNE = new Month("June", 30);
public static final Month JULY = new Month("July", 31);
public static final Month AUGUST = new Month("August", 31);
public static final Month SEPTEMBER = new Month("September",30);
public static final Month OCTOBER = new Month("October", 31);
public static final Month NOVEMBER = new Month("November", 30);
public static final Month DECEMBER = new Month("December", 31);
private final int days;
private final String name;
/**
* Explicit Value Constructor.
*
* @param name The name of the Month
* @param days The number of days in the Month
*/
private Month(String name, int days)
{
this.name = name;
this.days = days;
}
/**
* Get the 3-letter abbreviation for this Month.
*
* @return The 3-letter abbreviation
*/
public String getAbbreviation()
{
String result;
if (name.length() > 3) result = name.substring(0,3)+".";
else result = name;
return result;
}
/**
* Get the numeric value of this Month (in the interval [1,12]).
*
* @return The numeric value of this Month
*/
public int getNumber()
{
return ordinal()+1; // ordinal() returns the position in the declaration
}
/**
* Get the (normal) number of days in this Month.
*
* @return The normal number of days in this Month.
*/
public int getLength()
{
return days;
}
/**
* Return the Month that corresponds to a given String.
*
* @param s The String representation
* @return The corresponding Month
* @throws IllegalArgumentException if there is no match
*/
public Month parseMonth(String s) throws IllegalArgumentException
{
Month result;
String u;
u = s.toUpperCase();
result = Month.valueOf(u);
return result;
// A more elaborate version
//
// Month[] all;
// all = Month.values();
// for (int i=0; i<all.length; i++)
// {
// if (s.equalsIgnoreCase(all[i].name)
// || s.equalsIgnoreCase(all[i].getAbbreviation()))
// {
// return all[i];
// }
// }
// throw new IllegalArgumentException("No such Month");
}
/**
* Get a String representation of this Month
*
* @return The String representation (i.e., the name)
*/
public String toString()
{
return name;
}
}
compareTo()
ordinal()
valueOf()
values()
Month Class/**
* A class (rather than an enum) for the months of the year.
*
* @author Prof. David Bernstein, James Madison University
*/
public class Month
{
private static final Month[] VALUES = new Month[12];
private static int next = 0;
private static final String[] IDS =
{
"JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
"JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"
};
public static final Month JANUARY = new Month("January", 31);
public static final Month FEBRUARY = new Month("February", 28);
public static final Month MARCH = new Month("March", 31);
public static final Month APRIL = new Month("April", 30);
public static final Month MAY = new Month("May", 31);
public static final Month JUNE = new Month("June", 30);
public static final Month JULY = new Month("July", 31);
public static final Month AUGUST = new Month("August", 31);
public static final Month SEPTEMBER = new Month("September",30);
public static final Month OCTOBER = new Month("October", 31);
public static final Month NOVEMBER = new Month("November", 30);
public static final Month DECEMBER = new Month("December", 31);
private final int days;
private final String name;
/**
* Explicit Value Constructor.
*
* @param name The name of the Month
* @param days The number of days in the Month
*/
private Month(String name, int days)
{
this.name = name;
this.days = days;
VALUES[next] = this;
++next;
}
/**
* Compare this Month to the given month.
*
* @param other The Month of interest
* @return -1, 0, or 1
*/
public int compareTo(Month other)
{
if (this.ordinal() < other.ordinal()) return -1;
else if (this.ordinal() == other.ordinal()) return 0;
else return 1;
}
/**
* Get the 3-letter abbreviation for this Month.
*
* @return The 3-letter abbreviation
*/
public String getAbbreviation()
{
String result;
if (name.length() > 3) result = name.substring(0,3)+".";
else result = name;
return result;
}
/**
* Get the numeric value of this Month (in the interval [1,12]).
*
* @return The numeric value of this Month
*/
public int getNumber()
{
return ordinal()+1; // ordinal() returns the position in the declaration
}
/**
* Get the (normal) number of days in this Month.
*
* @return The normal number of days in this Month.
*/
public int getLength()
{
return days;
}
/**
* Return the ordinal value of this instance.
*
* @return The ordinal value (0-based)
*/
public int ordinal()
{
for (int i=0; i<VALUES.length; i++)
{
if (this == VALUES[i]) return i;
}
// Shouldn't get here!
return -1;
}
/**
* Return the Month that corresponds to a given String.
*
* @param s The String representation
* @return The corresponding Month
* @throws IllegalArgumentException if there is no match
*/
public Month parseMonth(String s) throws IllegalArgumentException
{
Month result;
String u;
u = s.toUpperCase();
result = Month.valueOf(u);
return result;
// A more elaborate version
//
// Month[] all;
// all = Month.values();
// for (int i=0; i<all.length; i++)
// {
// if (s.equalsIgnoreCase(all[i].name)
// || s.equalsIgnoreCase(all[i].getAbbreviation()))
// {
// return all[i];
// }
// }
// throw new IllegalArgumentException("No such Month");
}
/**
* Get a String representation of this Month
*
* @return The String representation (i.e., the name)
*/
public String toString()
{
return name;
}
/**
* Get all of the Month objects.
*
* @return An array containing all instances
*/
public static Month[] values()
{
return VALUES;
}
/**
* Get the Month associated with a particaulr identifier.
*
* @param s The identifier
* @return The corresponding Month (or null)
*/
public static Month valueOf(String s)
{
for (int i=0; i<IDS.length; i++)
{
if (s.equals(IDS[i])) return VALUES[i];
}
return null;
}
}