Перечисления с полями и методами
Добавляйте в перечисления поля, конструкторы и методы, чтобы инкапсулировать поведение.
«Перечисления с полями и методами» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Определение и использование перечислений
- Перечисления с полями и методами
- Выражения switch с перечислениями
- EnumSet и EnumMap