Java. Використання зчислень як класів

Використання зчислень як класів. Приклади оголошення зчислень, що містять конструктори, внутрішні поля, методи


Зміст


Пошук на інших ресурсах:

1. Особливості використання зчислень як класів. Використання конструкторів, полів та методів у зчисленнях

Усі зчислення, що оголошуються в програмі на мові Java є типами класів і успадковані від класу Enum. Таке успадкування значно розширює можливості зчислень. Зчислення можуть містити конструктори, інтерфейси, внутрішні поля, методи тощо. Використання різних складових в тілі зчислення працює так само як і в класах.

При оголошенні екземпляру зчислення не потрібно використовувати оператор new. Кожна іменована константа зчислення є об’єктом класу свого зчислення. Це означає, що при оголошенні конструктора в зчисленні цей конструктор викликається кожен раз при створенні константи зчислення.
Конструктор у зчисленні використовується так само як і в класі. З допомогою конструктора ініціалізуються значення іменованих констант зчислення. Зчислення може містити довільну кількість перевантажених конструкторів.

У спрощеному варіанті загальна форма оголошення та використання конструктора у зчисленні наступна:

enum EnumName {
  constant1(arguments1),
  constant2(arguments2),
  ...
  constantN(argumentsN);

  // Конструктор
  EnumName(list_of_parameters) {
    // ...
  }
}

тут

  • EnumName – ім’я типу зчислення;
  • constant1, constant2, constantN – іменовані константи зі зчислення, які приймають відповідно значення аргументів arguments1, agruments2, argumentsN;
  • EnumName(list_of_parameters) – конструктор зчислення, який отримує перелік параметрів list_of_parameters.

Поля (внутрішні змінні) в зчисленні, в основному застосовуються для збереження значень іменованих констант. Методи в зчисленні дозволяють проводити різні операції, обчислення над полями та отримувати доступ до іменованих констант. У зчисленнях не забороняється використовувати будь-яку кількість полів та методів для проведення обчислень чи деяких інших дій.

 

2. Приклади використання конструкторів, полів та методів у зчисленнях. Ініціалізація даних у зчисленні
2.1. Приклад встановлення кількості днів у місяці для іменованих констант

Умова задачі. Задано зчислення Months. З допомогою конструктора задати кожному місяцю значення кількості днів у цьому місяці.

Розв’язок.

// Зчислення, що описує місяці року
enum Months {
  // Іменовані константи - місяці року
  January(31), February(28), March(31), April(30), May(31), June(30),
  July(31), August(31), September(30), October(31), November(30), December(31);

  // Конструктор, необхідний для ініціалізації
  // іменованих констант (Jauary, February, ...) цілочисельними значеннями
  Months(int nDays) {
    this.nDays=nDays;
  }

  // Поле, що зберігає кількість днів,
  // наприклад, для константи January(31) значення nDays = 31
  private int nDays;

  // Метод, що повертає кількість днів
  public int getNDays() { return nDays; }
}

public class TrainEnumerations {

  public static void main(String[] args) {
    // Створити екземпляр типу Months та ініціалізувати його значенням
    Months mn = Months.April;

    // Викликати кількість днів у константі mn.April
    System.out.println(mn.getNDays());

    // Викликати кількість днів у константі Months.September
    System.out.println(Months.September.getNDays());
  }
}

Пояснимо виконання вищенаведеного коду. У вищенаведеному прикладі кожна константа ініціалізується цілочисельним значенням (January(31), February(28), …) завдяки використанню конструктора

Months(int nDays) {
  this.nDays=nDays;
}

Значення кількості днів зберігається у прихованому (private) внутрішньому полі

private int nDays;

Для того, щоб зчитувати поле nDays у клієнтському коді, потрібно в тілі зчислення Months створити загальнодоступний метод

// Метод, що повертає кількість днів
public int getNDays() { return nDays; }

Вищенаведений підхід дозволяє коректно зберігати та отримувати значення будь-яких типів в іменованих константах зчислення.

Результат виконання програми

30
30

 

2.2. Приклад використання зчислення, яке зберігає константи типу double

Умова задачі. Продемонструвати використання відомих математичних констант у зчисленні MathConstants. Використати константи для проведення обчислень.

Розв’язок.

Як відомо, кожна константа зчислення є об’єктом (екземпляром) типу цього зчислення. Тому, щоб зберігати константи типу double, потрібно створити відповідний конструктор. Цей конструктор буде отримувати параметром значення типу double, що буде ініціалізувати константу.
Для кожної константи потрібно зберігати значення, тому, в код зчислення вводиться додаткова внутрішня private-змінна яка це значення буде зберігати.
Текст програми, що розв’язує дану задачу, наступний

import java.util.Scanner;

// Зчислення, яке містить математичні константи типу double.
enum MathConstants {
  Pi(3.1415), Exp(2.71), G(9.81);
  // Внутрішнє поле, яке зберігає значення константи
  private double value;

  // Конструктор - необхідний для ініціалізації
  // констант значеннями, наприклад: Pi(3.1415)
  MathConstants(double x) {
    value = x;
  }

  // Метод необхідний для отримання значення константи
  public double Value() {
    return value;
  }
}

public class TrainEnumerations {

  public static void main(String[] args) {

    // Використання констант з плаваючою комою у зчисленнях
    // 1. Оголосити зчислення
    MathConstants mc;

    // 2. Щоб використати константу G,
    // потрібно викликати метод Value().
    mc = MathConstants.G;
    System.out.println("G = " + mc.Value()); // G = 9.81

    // 3. Використати константу Pi
    // для обчислення об'єму кулі за введеним радіусом
    Scanner inputDouble = new Scanner(System.in);
    System.out.print("radius = ");
    double radius = inputDouble.nextDouble();
    double volume = 4.0/3*MathConstants.Pi.Value()*radius*radius*radius;
    System.out.println("volume = " + volume);
  }
}

Тестовий приклад

G = 9.81
radius = 4
volume = 268.07466666666664

 

2.3. Приклад оголошення зчислення, в якому використовуються два конструктори.

Константи у зчисленні можуть ініціалізуватись різними способами. Для цього оголошується декілька відповідних конструкторів.
У прикладі, з метою демонстрації, ініціалізуються значення іменованих констант різними способами.

// Зчислення, в якому іменовані константи ініціалізуються різними конструкторами
enum Character {
  // Іменовані константи
  A('A'), // викликається конструктор з 1 параметром
  B('B'), // викликається конструктор з 1 параметром
  Enter('\n'), // викликається конструктор з 1 параметром
  SpaceBar; // викликається конструктор без параметрів

  // Конструктор, що отримує один параметр
  Character(char _symbol) {
    symbol = _symbol;
  }

  // Конструктор без параметрів, встановлює символ "пробіл"
  Character() {
    symbol = ' '; // клавіша пробіл
  }

  // Внутрішня змінна, яка зберігає символ
  private char symbol;

  // Метод доступу до змінної symbol
  public char getSymbol() { return symbol; }
}

public class TrainEnumerations {

  public static void main(String[] args) {

    // 1. Задати екземпляр зчислення типу Character
    Character ch = Character.B;

    // 2. Вивести значення екземпляру ch
    System.out.println(ch.getSymbol()); // B
  }
}

 

2.4. Приклад оголошення зчислення, в якому конструктор отримує 2 параметри

У прикладі оголошується зчислення PaperSize, яке описує формати листів за їх розмірами. Розмір кожного листа задається двома параметрами: шириною та висотою. Відповідно, константи зі зчислення отримують два значення. Для ініціалізації цих значень у зчисленні оголошується конструктор, який отримує 2 параметри.
Текст демонстраційної програми наступний

// Зчислення, що описує формати листів A1, A2, A3, A4, ...
enum PaperSize {
  // Формати листів
  A1(594, 841),
  A2(420, 594),
  A3(297, 420),
  A4(210, 297),
  A5(148, 210),
  A6(105, 148),
  A7(74, 105);

  // Конструктор з двома параметрами
  PaperSize(int width, int height) {
    this.width = width;
    this.height = height;
  }

  // Внутрішні змінні - розміри листа паперу
  private int width, height;

  // Методи доступу
  public int getWidth() { return width; }
  public int getHeight() { return height; }
}

public class TrainEnumerations {
  public static void main(String[] args) {
    // Використання зчислення PaperSize
    PaperSize ps = PaperSize.A2;

    // Вивести ширину та висоту
    System.out.println("Format " + ps.name() + ":");
    System.out.println("width = " + ps.getWidth() +
        " height = " + ps.getHeight());
  }
}

Результат виконання програми

Format A2:
width = 420 height = 594

 


Споріднені теми