In the previous lesson you learnt about constants.
Using enum for constants
You will commonly see the above technique of static final variables to define constants, including in the Java APIs. However, since Java version 5, a new and more powerful way of defining constants has been available, known as an enum (short for enumerated type). Enums are types in their own right (like classes and interfaces), so you should remove the following statements in Animal since they are no longer needed:
// Constants public static final String MALE = "m"; public static final String FEMALE = "f";
At the location where those constants were defined, declare the following lines instead:
// Define enum called Gender
public enum Gender {MALE, FEMALE};
Note the following:
- It is
publicbecause it contains only constants and is therefore safe for use outside of this class - The keyword
enumis a "type" (in the same way that that classes and interfaces are "types") - The name
Genderfollows the standard naming convention for types - The constants follow standard naming conventions for constants, i.e., are capitalised
You can now modify the Animal class to change the gender instance variable type from String to Gender:
private Gender gender; // the animal's gender
You also need to modify the constructor to specify Gender in place of String for the second parameter type:
public Animal(String name, Gender gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
dateAdmitted = new Date(); // today's date is assumed
// Add this animal's age to the combined age total
combinedAge += this.age;
}
You need to modify the getGender() and setGender() methods in a similar manner:
// Return the animal's gender
public Gender getGender() {
return gender;
}
// Change the animal's gender
public void setGender(Gender gender) {
this.gender = gender;
}
It would be useful for client objects to check whether an animal is male or female without having to invoke getGender() and do the check themselves. Define the following two methods in the Animal class:
public boolean isMale() {
return gender.equals(Gender.MALE);
}
public boolean isFemale() {
return gender.equals(Gender.FEMALE);
}
The equals() method is defined in Object and is therefore inherited by all classes. It serves to compare two objects to determine whether they are "equal" to each other, returning a boolean result. The equals() method for any enum compares whether the constant values are the same. You will learn more about the equals() method in Section 9, since it plays an important role in Java
Finally, you need to modify the constructors with the Animal subclasses Lion, Monkey and Penguin to specify Gender instead of String. For example, in class Lion:
public Lion(String myName, Gender myGender) {
this(myName, myGender, 0);
}
public Lion(String myName, Gender myGender, int myAge) {
super(myName, myGender, myAge);
}
Ensure you also modify Penguin and Monkey in the same way as above.
Client objects (such as Experiments) now specify the enum for the gender:
Animal leo = new Lion("Leo", Animal.Gender.MALE, 3);
leo.setGender(Animal.Gender.FEMALE);
Note the syntax above. You can read this as; use the MALE (or FEMALE) constant which exists within the Gender enum type, which in turn exists within class Animal.
Java will now ensure that only a valid Gender constant is supplied as argument values, so you can no longer supply nonsensical values as was the case previously.
Using an enum independently
Because an enum is a type in its own right you can define them independently rather than having to exist only within another class. Consider whether you think the gender constants could be useful in more than just animals? It seems likely that it could serve use elsewhere, such as to record the gender of the zookeepers or visitors (even though this is not currently recorded).
Therefore, you will now extract the Gender enum from inside the Animal class and make it a file in its own right.
First, remove the following lines from the Animal class:
// Define enum called Gender
public enum Gender {MALE, FEMALE};
Right-click on the virtualzoo.core package node and select New | Other... ensure Java is highlighted under Categories and select Java Enum... under File Types. Click Next >, enter Gender as the class name. Click Finish.
Complete the source code so that it looks as follows:
package virtualzoo.core;
public enum Gender {
MALE, FEMALE;
}
The Animal class will now locate the Gender enum from its separate location without any further modifications. Also, no further changes are needed to Lion, Monkey or Penguin – when the classes are recompiled they will locate the Gender enum in its separate file.
You do, however, need to make a small change in Experiments, since the enum is no longer defined inside Animal:
Animal leo = new Lion("Leo", Gender.MALE, 3);
leo.setGender(Gender.FEMALE);
It is possible to do much more with enums than merely defining constants – you can also define instance variables, constructors and methods.
In the next lesson you will learn about logical operators and the if condition.
Comments