0Pricing
Java Academy · Урок

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

Добавляйте в перечисления поля, конструкторы и методы, чтобы инкапсулировать поведение.

«Перечисления с полями и методами» — бесплатный урок Java Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

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

Константы перечисления могут содержать данные. Чтобы добавить поля, объявите их и конструктор. Конструктор автоматически является закрытым.

Объявление полей в перечислениях

Каждая константа перечисления вызывает конструктор при загрузке класса. Значения полей задаются один раз и неизменяемы, если поля объявлены неизменяемыми.

enum Planet {
    MERCURY(3.303e+23, 2.4397e6),
    VENUS  (4.869e+24, 6.0518e6),
    EARTH  (5.976e+24, 6.37814e6),
    MARS   (6.421e+23, 3.3972e6);

    private final double mass;    // kilograms
    private final double radius;  // meters

    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    public double mass()   { return mass; }
    public double radius() { return radius; }
}

Добавление методов в перечисления

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

enum Planet {
    EARTH(5.976e+24, 6.37814e6);
    // ... constructor and fields ...
    static final double G = 6.67300E-11;

    public double surfaceGravity() {
        return G * mass / (radius * radius);
    }

    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}

double earthWeight = 75.0;
double mass = earthWeight / Planet.EARTH.surfaceGravity();
for (Planet p : Planet.values())
    System.out.printf("Weight on %s: %.2f%n", p, p.surfaceWeight(mass));

Абстрактные методы констант перечисления

Каждая константа может предоставить собственную реализацию абстрактного метода, объявленного в теле перечисления.

enum Operation {
    PLUS  { public double apply(double x, double y) { return x + y; } },
    MINUS { public double apply(double x, double y) { return x - y; } },
    TIMES { public double apply(double x, double y) { return x * y; } },
    DIVIDE{ public double apply(double x, double y) { return x / y; } };

    public abstract double apply(double x, double y);
}

System.out.println(Operation.PLUS.apply(3, 4));   // 7.0
System.out.println(Operation.TIMES.apply(3, 4));  // 12.0

Перечисления с текстовыми метками

Распространённый шаблон: каждой константе присваивается понятная пользователю метка, хранящаяся в поле.

enum UserRole {
    GUEST("Guest User"),
    MEMBER("Registered Member"),
    ADMIN("Administrator"),
    SUPERADMIN("Super Administrator");

    private final String label;

    UserRole(String label) { this.label = label; }

    public String label() { return label; }

    public static UserRole fromLabel(String lbl) {
        for (UserRole r : values())
            if (r.label.equalsIgnoreCase(lbl)) return r;
        throw new IllegalArgumentException(lbl);
    }
}

System.out.println(UserRole.ADMIN.label()); // Administrator

Перечисление с несколькими полями

Перечисления могут иметь столько полей, сколько необходимо. В этом примере перечисление валюты хранит код ISO и символ.

enum Currency {
    USD("US Dollar", "$"),
    EUR("Euro", "\u20ac"),
    GBP("British Pound", "\u00a3"),
    JPY("Japanese Yen", "\u00a5");

    public final String name;
    public final String symbol;

    Currency(String name, String symbol) {
        this.name = name;
        this.symbol = symbol;
    }

    public String format(double amount) {
        return String.format("%s%.2f", symbol, amount);
    }
}

System.out.println(Currency.EUR.format(99.99)); // \u20ac99.99

Переопределение toString()

Переопределите toString() в перечислении, чтобы возвращать пользовательское строковое представление вместо имени константы.

enum HttpMethod {
    GET, POST, PUT, PATCH, DELETE;

    @Override
    public String toString() {
        return name().toUpperCase();
    }

    public boolean hasBody() {
        return this == POST || this == PUT || this == PATCH;
    }
}

HttpMethod m = HttpMethod.POST;
System.out.println(m);            // POST
System.out.println(m.hasBody());  // true
System.out.println(HttpMethod.GET.hasBody()); // false

Перечисление с проверкой данных

Конструкторы перечислений могут проверять свои аргументы, предотвращая создание недопустимых состояний.

enum DiscountTier {
    BRONZE(5), SILVER(10), GOLD(20), PLATINUM(30);

    public final int percentage;

    DiscountTier(int percentage) {
        if (percentage < 0 || percentage > 100)
            throw new IllegalArgumentException("Invalid: " + percentage);
        this.percentage = percentage;
    }

    public double apply(double price) {
        return price * (1 - percentage / 100.0);
    }
}

System.out.println(DiscountTier.GOLD.apply(100.0)); // 80.0

Шаблон одиночки для перечисления

Перечисление с единственной константой — самый безопасный способ реализовать одиночку в Java: оно безопасно при сериализации и по умолчанию безопасно в многопоточной среде.

enum AppConfig {
    INSTANCE;

    private String dbUrl = "jdbc:postgresql://localhost/mydb";
    private int maxConnections = 20;

    public String getDbUrl() { return dbUrl; }
    public int getMaxConnections() { return maxConnections; }

    public void setDbUrl(String url) { this.dbUrl = url; }
}

// Access the singleton
AppConfig config = AppConfig.INSTANCE;
System.out.println(config.getDbUrl());

Перечисления в предметных моделях

Перечисления широко используются в предметных моделях для представления типобезопасных категорий: статус заказа, способ оплаты, тип уведомления и другие.

enum PaymentMethod {
    CREDIT_CARD("Credit Card", true),
    DEBIT_CARD("Debit Card", true),
    PAYPAL("PayPal", false),
    CRYPTO("Cryptocurrency", false),
    BANK_TRANSFER("Bank Transfer", false);

    public final String displayName;
    public final boolean instantCharge;

    PaymentMethod(String displayName, boolean instantCharge) {
        this.displayName = displayName;
        this.instantCharge = instantCharge;
    }
}

Поле перечисления и вычисляемое значение

Поля хранят фиксированные данные, а методы вычисляют динамические значения. Используйте поля для постоянных данных, а методы — для производных значений.

enum DayType {
    MONDAY(false), TUESDAY(false), WEDNESDAY(false),
    THURSDAY(false), FRIDAY(false),
    SATURDAY(true), SUNDAY(true);

    private final boolean weekend;
    DayType(boolean weekend) { this.weekend = weekend; }

    public boolean isWeekend()  { return weekend; }
    public boolean isWeekday()  { return !weekend; }

    public static long weekdayCount() {
        return java.util.Arrays.stream(values())
            .filter(DayType::isWeekday).count();
    }
}
System.out.println(DayType.weekdayCount()); // 5

Быстрая проверка

Чем конструктор перечисления отличается от конструктора обычного класса?

Итоги: перечисления с полями и методами

Главные выводы:

  • Добавляйте поля и конструктор, чтобы хранить данные для каждой константы
  • Конструкторы перечислений неявно являются закрытыми
  • Абстрактные методы позволяют каждой константе предоставлять собственную реализацию
  • Переопределяйте toString() для пользовательских отображаемых имён
  • Перечисления с единственной константой — лучший способ реализации одиночки
  • Перечисления естественно встраиваются в предметные модели как типобезопасные категории

Часто задаваемые вопросы

Урок «Перечисления с полями и методами» бесплатный?

Да — полный текст урока «Перечисления с полями и методами» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «Перечисления с полями и методами»?

Добавляйте в перечисления поля, конструкторы и методы, чтобы инкапсулировать поведение. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Перечисления с полями и методами»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Определение и использование перечислений
  2. Перечисления с полями и методами
  3. Выражения switch с перечислениями
  4. EnumSet и EnumMap
← Назад к Java Academy