Урок 10

Перечисления


1. Что такое перечисления?

Перечисления создаются использованием ключевого слова enum. В простейшей форме перечисления - это список именованных констант. Каждая константа перечисления является объектом класса, в котором она определена.

Константы перечисления являются static final и не могут быть изменены после создания.

Перечисления добавлены в Java 5.

Пример 1. Перечисление

public enum CoffeeSize {
    BIG, HUGE, OVERWHELMING
}

До введения перечисления те же задачи решались с помощью использования констант, например:

Пример 2. Использование констант вместо перечисления

public class CoffeeSize5 {
    public static final String BIG = "BIG";
    public static final String HUGE = "HUGE";
    public static final String OVERWHELMING = "OVERWHELMING";
}

2. Использование в операторе switch

Значения перечислимого типа можно также использовать в управляющем операторе switch.

В выражениях ветвей case должны использоваться константы из того же самого перечисления, что и в самом операторе switch. В выражениях ветвей case имена констант указываются без уточнения имени их перечислимого типа. Тип перечисления в операторе switch уже неявно задает тип enum для операторов case.

Пример 3. Использование перечисления в операторе switch

public class CoffeeSizeDemo2 {
    public static void main(String[] args) {
        CoffeeSize coffeeSize = CoffeeSize.BIG;
        switch (coffeeSize) {
            case BIG:
                System.out.println("Дайте мне большую чашку кофе!");
                break;
            case HUGE:
                System.out.println("Дайте мне огромную чашку кофе!");
                break;
            case OVERWHELMING:
                System.out.println("Дайте мне громадную чашку кофе!");
                break;
            default:
                System.out.println("Чашка не выбрана.");
        }
    }
}

3. Класс java.lang.Enum

Перечисление в Java относится к типу класса. Перечисления НЕ может наследоваться от другого класса и НЕ может быть суперклассом.

Все перечисления автоматически наследуют от класса java.lang.Enum. В этом классе определяется ряд методов, доступных для использования во всех перечислениях: ordinal(), compareTo(), equals(), values() и valueOf().

Перечисления также неявно наследуют интерфейсы Serializable и Comparable.

3.1. Методы values() и valueOf()

Метод values() возвращает массив, содержащий список констант перечислимого типа.

Метод valueOf() возвращает константу перечислимого типа, значение которой соответствует символьной строке, переданной в качестве аргумента.

Пример 4. Использование методов values() и valueOf()

public class CoffeeSizeDemo3 {
    public static void main(String[] args) {
        CoffeeSize coffeeSize;
        System.out.println("Константы перечислимого типа CoffeeSize:");
        CoffeeSize[] coffeeSizes = CoffeeSize.values();
        for (CoffeeSize c : coffeeSizes) {
            System.out.println(c);
        }
        System.out.println();

        coffeeSize = CoffeeSize.valueOf("BIG");
        System.out.println("Переменная coffeeSize содержит " + coffeeSize);
    }
}

3.2. Метод ordinal()

Вызвав метод ordinal(), можно получить значение, которое обозначает позицию константы в списке констант перечислимого типа. Порядковые значения начинаются с нуля.

Пример 5. Использование метода ordinal()

public class CoffeeSizeDemo4 {
    public static void main(String[] args) {
        for (CoffeeSize c : CoffeeSize.values()) {
            System.out.println(c + " " + c.ordinal());
        }
    }
}

3.3. Метод compareTo()

С помощью метода compareTo(типПеречисления e) можно сравнить порядковые значения двух констант одного и того же перечислимого типа.

Если порядковое значение вызывающей константы меньше, чем у константы е, то метод compareTo() возвращает отрицательное значение.

Если порядковые значения обеих констант одинаковы, возвращается нуль.

Если порядковое значение вызывающей константы больше, чем у константы е, то возвращается положительное значение.

Пример 6. Использование метода compareTo()

public class CoffeeSizeDemo5 {
    public static void main(String[] args) {
        CoffeeSize coffeeSize1 = CoffeeSize.BIG;
        CoffeeSize coffeeSize2 = CoffeeSize.HUGE;
        CoffeeSize coffeeSize3 = CoffeeSize.BIG;

        if (coffeeSize1.compareTo(coffeeSize2) < 0) {
            System.out.println(coffeeSize1 + " предшествует " + coffeeSize2);
        }
        if (coffeeSize1.compareTo(coffeeSize2) > 0) {
            System.out.println(coffeeSize2 + " предшествует " + coffeeSize1);
        }
        if (coffeeSize1.compareTo(coffeeSize3) == 0) {
            System.out.println(coffeeSize1 + " равно " + coffeeSize3);
        }
    }
}

3.4. Метод equals()

Вызвав метод equals(), переопределяющий аналогичный метод из класса Object, можно сравнить на равенство константу перечислимого типа с любым другим объектом. Но оба эти объекта будут равны только в том случае, если они ссылаются на одну и ту же константу из одного и того же перечисления. Простое совпадение порядковых значений не вынудит метод equals() возвратить логическое значение true, если две константы относятся к разным перечислениям.

Пример 7. Использование метода equals()

public class CoffeeSizeDemo6 {
    public static void main(String[] args) {
        CoffeeSize coffeeSize1 = CoffeeSize.BIG;
        CoffeeSize coffeeSize2 = CoffeeSize.HUGE;
        CoffeeSize coffeeSize3 = CoffeeSize.BIG;

        if (coffeeSize1.equals(coffeeSize2)) {
            System.out.println("Oшибкa!");
        }
        if (coffeeSize1.equals(coffeeSize3)) {
            System.out.println(coffeeSize1 + " равно " + coffeeSize3);
        }
        if (coffeeSize1 == coffeeSize3) {
            System.out.println(coffeeSize1 + " == " + coffeeSize3);
        }
    }
}

4. Возможности перечисления

Создать экземпляр перечисления с помощью оператора new нельзя, но в остальном перечисление обладает всеми возможностями, которые имеются у других классов.

Перечисления допускают предоставление конструкторов, добавление переменных экземпляров и методов и даже реализацию интерфейсов.

Конструктор перечисления является private по умолчанию.

Пример 8. Использование конструктора, переменной экземпляра и метода в перечислении

public enum CoffeeSize2 {
    // 8, 10 and 16 are passed to the constructor
    BIG(8), HUGE(10), OVERWHELMING(16);

    CoffeeSize2(int ounces) { // constructor
        this.ounces = ounces;
    }

    private int ounces; // an instance variable

    public int getOunces() {
        return ounces;
    }
}
public class Coffee2 {
    CoffeeSize2 size;

    public static void main(String[] args) {
        Coffee2 drink1 = new Coffee2();
        drink1.size = CoffeeSize2.BIG;

        Coffee2 drink2 = new Coffee2();
        drink2.size = CoffeeSize2.OVERWHELMING;

        System.out.println(drink1.size.getOunces());
        for (CoffeeSize2 coffeeSize : CoffeeSize2.values()) {
            System.out.println(coffeeSize + " " + coffeeSize.getOunces());
        }
    }
}

Пример 9. Использование перегружаемых форм конструкторов

public enum CoffeeSize3 {
    BIG(8), HUGE, OVERWHELMING(16);

    CoffeeSize3(int ounces) { // constructor
        this.ounces = ounces;
    }

    CoffeeSize3() {
        this.ounces = -1;
    }

    private int ounces;

    public int getOunces() {
        return ounces;
    }
}

5. Объявление перечислений

Перечисления могут быть объявлены: отдельным классом или как член класса. Но НЕ могут быть объявлены внутри метода.

Пример 10. Объявление перечисления в качестве члена класса

public class Coffee3 {
    enum CoffeeSize { BIG, HUGE, OVERWHELMING }

    CoffeeSize size;
}
public class CoffeeTest2 {
    public static void main(String[] args) {
        Coffee3 drink = new Coffee3();
        drink.size = Coffee3.CoffeeSize.BIG; // enclosing class name required
    }
}

Пример 11. Объявление перечисления в методе

public class CoffeeTest3 {
    public static void main(String[] args) {
        // WRONG! Cannot declare enums in methods
        /*enum CoffeeSize {BIG, HUGE, OVERWHELMING}
        Coffee drink = new Coffee();
        drink.size = CoffeeSize.BIG;*/
    }
}

6. Переопределение методов

Пример 12. Переопределение метода перечисления

public enum CoffeeSize4 {
    BIG(8),
    HUGE(10),
    OVERWHELMING(16) {
        // start a code block that defines the "body" for this constant
        public String getLidCode() {
            // override the method defined in CoffeeSize
            return "A";
        }
    }; // the semicolon is REQUIRED when more code follows

    CoffeeSize4(int ounces) {
        this.ounces = ounces;
    }

    private int ounces;

    public int getOunces() {
        return ounces;
    }

    // this method is overridden by the OVERWHELMING constant
    public String getLidCode() {
        // the default value we want to return for CoffeeSize4 constants
        return "B";
    }
}
public class CoffeeSizeDemo7 {
    public static void main(String[] args) {
        for (CoffeeSize4 coffeeSize : CoffeeSize4.values()) {
            System.out.println(coffeeSize + " " + coffeeSize.getLidCode());
        }
    }
}

7. Перечисления и интерфейсы

Перечисления могут реализовывать интерфейсы:

Пример 13. Перечисление реализующее интерфейс

public enum Currency implements Runnable {
    PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
    private int value;

    Currency(int value) {
        this.value = value;
    }

    @Override
    public void run() {
        System.out.println("Enum in Java implement interfaces");
    }
}

 

Источники: Java Enum Tutorial: 10 Examples of Enum in Java Read more



0 comments
Leave your comment: