CodeGym /Java блог /Случаен /Enum клас в Java
John Squirrels
Ниво
San Francisco

Enum клас в Java

Публикувано в групата
здрасти В тази статия ще ви разкажем за Java Enums . Представете си, че ви е дадена следната задача: създайте клас, който прилага дните от седмицата . На пръв поглед това изглежда доста лесно. Вашият code ще изглежда така:

public class DayOfWeek {

   private String title;

   public DayOfWeek(String title) {
       this.title = title;
   }

   public static void main(String[] args) {
       DayOfWeek dayOfWeek = new DayOfWeek("Saturday");
       System.out.println(dayOfWeek);
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
Всичко изглежда наред, но има един проблем: можете да предадете всеки текст на конструктора на класа DayOfWeek . Това означава, че някой може да създаде ден от седмицата, наречен "Жаба", "Облак" or "azaza322". Това очевидно не е поведението, което очакваме, тъй като има само 7 реални дни от седмицата и всеки от тях има конкретно име. Следователно нашата задача е по няHowъв начин да ограничим диапазона от възможни стойности за класа DayOfWeek . Преди да се появи Java 1.5, разработчиците трябваше самостоятелно да измислят свои собствени решения на този проблем, тъй като езикът нямаше готово решение. В онези дни, ако програмистите трябваше да ограничат броя на стойностите, те правеха следното:

public class DayOfWeek {

   private String title;

   private DayOfWeek(String title) {
       this.title = title;
   }

   public static DayOfWeek SUNDAY = new DayOfWeek("Sunday");
   public static DayOfWeek MONDAY = new DayOfWeek("Monday");
   public static DayOfWeek TUESDAY = new DayOfWeek("Tuesday");
   public static DayOfWeek WEDNESDAY = new DayOfWeek("Wednesday");
   public static DayOfWeek THURSDAY = new DayOfWeek("Thursday");
   public static DayOfWeek FRIDAY = new DayOfWeek("Friday");
   public static DayOfWeek SATURDAY = new DayOfWeek("Saturday");

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
Ето Howво трябва да забележите:
  • Конструкторът е частен. Ако конструкторът е маркиран с частния модификатор, той не може да се използва за създаване на обект. И тъй като класът има само един конструктор, никога не могат да бъдат създадени обекти DayOfWeek .

    
    	public class Main {
    
       		public static void main(String[] args) {
          
           			DayOfWeek sunday = new DayOfWeek(); // Error!
       		}
    }
    

  • Разбира се, класът има необходимия брой публични статични обекти, които са правилно инициализирани (използвайки правилните имена на дните от седмицата).

    Това позволи тези обекти да се използват в други класове.

    
    	public class Person {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = DayOfWeek.SUNDAY;
    
           			System.out.println(sunday);
      		 }
    }
    

    Изход:

    DayOfWeek{title = 'неделя'}

Този подход до голяма степен решава проблема. Имаме 7 дни от седмицата на наше разположение и никой не може да създава нови. Това решение е предложено от Джошуа Блок в книгата му Ефективна Java . Между другото, тази книга е много готина и трябва да се прочете за всеки разработчик на Java. Как да използваме класа Enum - 2С пускането на Java 1.5 езикът получи готово решение за такива ситуации: Java Enums . Enum в Java също е клас. Той е специално "фино настроен" за решаване на проблеми като този, т.е. създаване на определен ограничен диапазон от стойности. Създателите на Java вече имаха готови примери (например C вече имаше enum ), така че успяха да създадат най-добрия вариант.

И така, Howво е Java Enum?

Нека преразгледаме нашия пример за DayOfWeek :

public enum DayOfWeek {

   SUNDAY,
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY
}
Сега това изглежда много по-просто :) Вътрешно нашият Enum има 7 статични константи. И това е нещо, което можем да използваме за реализиране на програма. Например, нека напишем програма, която определя дали ученикът трябва да ходи на учorще днес. Нашият ученик ще има дневен график, представен от класа StudentSchedule :

public class StudentSchedule {

   private DayOfWeek dayOfWeek;
   // ... other fields


   public DayOfWeek getDayOfWeek() {
       return dayOfWeek;
   }

   public void setDayOfWeek(DayOfWeek dayOfWeek) {
       this.dayOfWeek = dayOfWeek;
   }
}
Променливата dayOfWeek на обекта график определя кой ден е днес. А ето и нашия ученически клас:

public class Student {

   private StudentSchedule schedule;
   private boolean goToSchool;

   public void wakeUp() {
      
       if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
           System.out.println("Hooray, you can sleep more!");
       } else {
           System.out.println("Damn, time for school again :(");
       }
   }
}
В метода wakeUp() ние използваме Java Enum , за да определим Howво следва да направи ученикът. Дори не предоставихме подробности за всяко поле в DayOfWeek и не е нужно: очевидно е How трябва да работят дните от седмицата. Ако го използваме в сегашния му вид, всеки разработчик ще разбере Howво се случва в нашия code. Друг пример за удобството на Enum е, че неговите константи могат да се използват с командата switch. Например, нека напишем програма за строга диета, в която ястията са планирани по дни:

public class VeryStrictDiet {
   public void takeLunch(DayOfWeek dayOfWeek) {
       switch (dayOfWeek) {
           case SUNDAY:
               System.out.println("Sunday Dinner! You can even enjoy something a little sweet today.");
               break;
           case MONDAY:
               System.out.println("Lunch for Monday: chicken noodle soup!");
               break;
           case TUESDAY:
               System.out.println("Tuesday, today it's celery soup :(");
               break;
               //... and so on to the end
       }
   }
}
Това е едно от предимствата на Enum пред старото решение, използвано преди Java 1.5 — старото решение не можеше да се използва с switch . Какво друго трябва да знаете за Enum ? Enum е истински клас с всички възможности, които това включва. Например, ако текущата реализация на дните от седмицата е неадекватна, можете да добавите променливи, конструктори и методи към DayOfWeek :

public enum DayOfWeek {
  
   SUNDAY ("Sunday"),
   MONDAY ("Monday"),
   TUESDAY ("Tuesday"),
   WEDNESDAY ("Wednesday"),
   THURSDAY ("Thursday"),
   FRIDAY ("Friday"),
   SATURDAY ("Saturday");

   private String title;

   DayOfWeek(String title) {
       this.title = title;
   }

   public String getTitle() {
       return title;
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
Сега нашите константи Enum имат поле за заглавие , метод за получаване и заменен метод toString . В сравнение с обикновените класове, на Enum беше поставено едно сериозно ограничение — не може да се наследи. Освен това изброяванията имат характерни методи:
  • values() : връща масив от всички стойности в Enum :

    
    public static void main(String[] args) {
       		System.out.println(Arrays.toString(DayOfWeek.values()));
    }
    

    Изход:

    [DayOfWeek{title = 'неделя'}, DayOfWeek{title = 'понеделник'}, DayOfWeek{title = 'вторник'}, DayOfWeek{title = 'сряда'}, DayOfWeek{title = 'четвъртък'}, DayOfWeek{title = 'петък'}, ден от седмицата{title = 'събота'}]

  • ordinal() : връща поредния номер на константата. Номерацията започва от нула:

    
    	public static void main(String[] args) {
    
       		int sundayIndex = DayOfWeek.SUNDAY.ordinal();
       		System.out.println(sundayIndex);
    }
    

    Изход:

    0

  • valueOf() : връща обекта Enum , който съответства на предаденото име:

    
    public static void main(String[] args) {
       DayOfWeek sunday = DayOfWeek.valueOf("SUNDAY");
       System.out.println(sunday);
    }
    

    Изход:

    DayOfWeek{title = 'неделя'}

Забележка:ние използваме главни букви, за да посочим Enum полета. Това са константи, така че те използват само главни букви, а не CamelCase .
Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION