Enums


J2SE 5.0 introduces the notion of an enumerated typea type that constrains all possible values to a discrete list. For example, if you implement a class that represents a deck of cards, you know that the only possible suit values are clubs, diamonds, spades, and hearts. There are no other suits. For grades, you know there are only five possible letter grades.

You can define grades as strings, as in the above GPA code, and use String values to represent possible letter grades. While this will work, it has some problems. First, it is easy to make a mistake when typing all the various strings. You can create class constants to represent each letter grade (which we probably should have done in the above code), and as long as all code uses the constants, things are fine.

Even if you have supplied class constants, client code can still pass an invalid value into your code. There is nothing that prevents a user of the Student class from executing this line of code:

 student.addGrade("a"); 

The results are probably not what you expectyou wrote the code to handle only uppercase grade letters.

You can instead define an enum named Grade. The best place for this, for now, is within the Student class:

 public class Student {    enum Grade {A, B, C, D, F };    ... 

Using enum results in the declaration of a new type. In this case, you have just created a new type named Student.Grade, since you defined the Grade enum within the Student class. The new enum has five possible values, each representing a named object instance.

Change the test to use the enum instances:

 public void testCalculateGpa() {    Student student = new Student("a");    assertGpa(student, 0.0);    student.addGrade(Student.Grade.A);    assertGpa(student, 4.0);    student.addGrade(Student.Grade.B);    assertGpa(student, 3.5);    student.addGrade(Student.Grade.C);    assertGpa(student, 3.0);    student.addGrade(Student.Grade.D);    assertGpa(student, 2.5);    student.addGrade(Student.Grade.F);    assertGpa(student, 2.0); } 

In the Student class, you will need to change any code that declared a grade to be of the type String to now be of the type Grade. Since the Grade enum is defined within Student, you can refer to it directly (i.e., as Grade instead of Student.Grade).

 public class Student implements Comparable<Student> {    enum Grade {A, B, C, D, F };    ...    private ArrayList<Grade> grades = new ArrayList<Grade>();    ...    void addGrade(Grade grade) {       grades.add(grade);    }    ...    double getGpa() {       if (grades.isEmpty())          return 0.0;       double total = 0.0;       for (Grade grade: grades)          total += gradePointsFor(grade);       return total / grades.size();    }   ...    int gradePointsFor(Grade grade) {       if (grade == Grade.A) return 4;       if (grade == Grade.B) return 3;       if (grade == Grade.C) return 2;       if (grade == Grade.D) return 1;       return 0;    }    ... } 

The method gradePointsFor compares the value of the parameter grade to each of the enum values in turn. Each of the enum values represents a unique instance in memory. This allows you to make the comparison using the == operator instead of the equals method. Remember that the == operator is used for comparing two object references: Do the two references point to the same object in memory?

It is no longer possible for a client to pass in an invalid value to the method addGrade. Client code cannot create a new instance of Grade. The five instances specified in the enum declaration within Student are all that exist.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net