Use interfaces to define constants? public interface ScienceConstants { static final double PI = 3.14; static final double BOLTZMANN_CONSTANT = 1.3806503e-23; } 4/13/2015 Good Java Programming 1 Alternative 1 Use Enums Enums in Java are full fledged classes (Java 1.5) More powerful than enums in C++ • where they are just int values By nature, Enums are immutable 4/13/2015 All fields should be final Make the fields private and provide accessors/mutators Good Java Programming 2 Do NOT use interfaces to define constants The use of constants in a class should be considered implementation detail If a non-final class implements an interface, all its subclasses will have their namespaces polluted by the constants in the interface Java uses constant interfaces in its libraries (example: java.io.ObjectStreamConstants) 4/13/2015 treat these as anomalies Good Java Programming 3 Alternative 2 Use Constant Utility class public class PhsyicalConstants { private PhysicalConstants() { } //prevent instantiation static final double PI = 3.14; static final double BOLTZMANN_CONSTANT = 1.3806503e-23; } Usage: double circ = 2 * PhysicalConstants.PI * radius; 4/13/2015 Good Java Programming 4 Alternative 2: continued Use Constant Utility class If it is heavily used, then you don’t need to qualify it each time use static import facility, introduced in java 1.5 public class MyTest { import static PhysicalConstants.*; double myMethod () { double circ = 2 * PI * radius; … } } 4/13/2015 Good Java Programming 5 More on Enums Java Enums are classes that export one instance for each enumeration constant via a public static final field Enum types are effectively final no accessible constructor clients can neither create instances or extend it so, enum types are instance controlled Enums are generalization of Singletons Singleton is a single element enum 4/13/2015 Good Java Programming 6 More on Enums (2) Enums provide compile-time type safety Enums with identically named constants can coexist as each type has its own namespace Can augment Enums with methods 4/13/2015 just like any Java class Good Java Programming 7 More on Enums (3) Has a static values(…) method that returns an array of its values in the order it was declared example in next slides Default toString() returns the declared name of each enum value 4/13/2015 can be overridden Good Java Programming 8 Enum Example public enum CourseAnalysis { cs240 (4, 81.5, 55), cs342 (4, 84.3, 35), cs654 (3, 79.8, 41); // semi colon here private final int numCredits; private final double avgScore; private final int numStudents; private static final double NO_OF_EXAMS = 3; // Constructor CourseAnalysis(int numCreditsIn, double avgScoreIn, int numStudentsIn) { numCredits = numCreditsIn; avgScore = avgScoreIn; numStudents = numStudentsIn; } 4/13/2015 Good Java Programming 9 Enum Example (continued) public int getNumCredits() { return numCredits; } public double getAvgScore() { return avgScore; } public int getNumStudents() { return numStudents; } // dummy method, just an example // note: calculation is not intended to make sense … public double someWeightedAverage(double weight) { return weight * numCredits * avgScore / numStudents; } } 4/13/2015 Good Java Programming 10 Enum: can’t instantiate like a Java object // Try calling the constructor CourseAnalysis cA = new CourseAnalysis(3, 3.14, 7); Driver.java:91: enum types may not be instantiated [javac] CourseAnalysis cA = new CourseAnalysis(3, 3.14, 7); [javac] ^ [javac] 1 error BUILD FAILED 4/13/2015 Good Java Programming 11 Enum: cannot directly access private data members // try to access the private data member directly System.out.printf("Enum member: average score is %f ", CourseAnalysis.cs342.avgScore); Error: avgScore has private access in test.util.CourseAnalysis 4/13/2015 Good Java Programming 12 Enum: default toString() System.out.printf("Enum member is %s %n", CourseAnalysis.cs342); Output: [java] Enum member is cs342 4/13/2015 Good Java Programming 13 Enum: accessing methods // access methods like a standard Java object System.out.printf("Enum member: average score is %f %n", CourseAnalysis.cs342.getAvgScore()); Output: [java] Enum member: average score is 84.300000 4/13/2015 Good Java Programming 14 Enum: foreach double weightValue = 0.77; for (CourseAnalysis c : CourseAnalysis.values()) { System.out.printf("WeightedAvg of %s is %f %n", c, c.someWeightedAverage(weightValue)); } [java] WeightedAvg of cs240 is 4.564000 [java] WeightedAvg of cs342 is 7.418400 [java] WeightedAvg of cs654 is 4.496049 4/13/2015 Good Java Programming 15 Design Guideline The constant interface pattern is a poor use of interfaces 4/13/2015 Good Java Programming 16