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; } }