Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Enum to hold object constants

So I've learned a bunch recently so I'm going back and sort of refactoring the homeworks from a previous course that I took to implement them using good practices. One homework had us implement a Planner object that contained an array of Course objects. I'm trying to create some Course constants so that I can access some popular Courses without having to create brand new Objects every time and so I can easily access them without going through the Course building process. I don't have much experience with enums and I can't seem to find anything on how I can actually use an Enum to store constants that are Objects. I originally wanted to make them constants in the Course class but Effective Java insists enumns should be used in such a situation. Does my implementation make sense at all? How should I go about making this enum that contains Course constants so I can actually retrieve them? I use the Builder method for creating a Course.

public enum Courses {
    CSE_114, CSE_214, CSE_219, CSE_215;

    private final static Course CSE_114_COURSE = new Course
        .Builder("Computer Science 1", "Paul Fodor", 114)
        .section((byte)1).department("CSE").build();

    private static final Course CSE_214_COURSE = new Course
        .Builder("Data Structures", "Ahmad Esmaili", 214)
        .section((byte)1).department("CSE").build();

    private static final Course CSE_219_COURSE = new Course
        .Builder("Software Development", "Richard McKenna", 219)
        .section((byte)1).department("CSE").build();

    private static final Course CSE_215_COURSE = new Course
        .Builder("Foundations of CS", "Paul Fodor", 215)
        .section((byte)1).department("CSE").build();

    public static Course get(Courses c) {
        switch(c) {
            case CSE_114: return CSE_114_COURSE;
            case CSE_214: return CSE_214_COURSE;
            case CSE_219: return CSE_219_COURSE;
            case CSE_215: return CSE_215_COURSE;
            default: throw new IllegalArgumentException("Course does not exist.");
    }
}
}
like image 370
VladYev Avatar asked Feb 06 '16 19:02

VladYev


People also ask

Can enum hold objects?

An enum can, just like a class , have attributes and methods. The only difference is that enum constants are public , static and final (unchangeable - cannot be overridden). An enum cannot be used to create objects, and it cannot extend other classes (but it can implement interfaces).

Should I use enum for constants?

You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time—for example, the choices on a menu, command line flags, and so on.

Can we define constants in enum?

The enum type, introduced in Java 5, is a special data type that represents a group of constants. Using enums, we can define and use our constants in the way of type safety.

How do you use constants in enum?

An enum is a special class that represents a group of constants. To create an enum, use the enum keyword (instead of class or interface), and separate the constants with a comma. values() method can be used to return all values present inside enum.


1 Answers

You can actually treat an enum like an object:

public enum Course {
    CSE_114("Computer Science 1", "Paul Fodor");

    public final String room;
    public final String lecturer;

    private Course(room, lecturer) {
        this.room = room;
        this.lecturer = lecturer;
    }
}

Because it is an enum, all values must be known at compile time. This is enforced by the Java language, which requires that the enum constructor is private.

While this would work for your situation, I don't recommend it - in fact, I don't recommend using an enum at all. An enum represents a fixed, known set of values. If you want to create more courses at runtime, then the enum is incomplete, and that contradicts the definition of an enum.

Instead, I suggest you use a CourseManager. Create one class, which holds the collection of all known courses. Then, when you need a course, you request it by name.

Course cs114 = courses.get("CS 114");

You could also take it one step further, by instantiating the CourseManager from a file, which contains a list of courses in a basic format like JSON.

like image 160
Andrew Williamson Avatar answered Oct 08 '22 23:10

Andrew Williamson