JavaRush /وبلاگ جاوا /Random-FA /Enum در جاوا. نمونه های عملی اضافه کردن سازنده ها و روش ه...

Enum در جاوا. نمونه های عملی اضافه کردن سازنده ها و روش ها

در گروه منتشر شد
سلام! امروز ما در مورد یک نوع داده خاص در جاوا صحبت خواهیم کرد - Enum(مخفف برای enumeration). ویژگی آنها چیست؟ بیایید تصور کنیم که باید ماه ها را در برنامه پیاده کنیم. Enum.  نمونه های عملی  اضافه کردن سازنده ها و روش ها - 1به نظر می رسد، مشکل چیست؟ فقط باید مشخص کنید که هر ماه چه خواصی دارد. شاید اول از همه به نام ماه و تعداد روزهای آن نیاز داشته باشیم. راه حل مشکل بسیار ساده به نظر می رسد:
public class Month {

   private String name;
   private int daysCount;

   public Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getDaysCount() {
       return daysCount;
   }

   public void setDaysCount(int daysCount) {
       this.daysCount = daysCount;
   }

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
مجموعه کامل لطفا! ما یک کلاس داریم Month، فیلدهای لازم، getters-setters، toString(). مگر اینکه برای شادی کامل نیاز به اضافه کردنش equals()داشته باشید hashCode():) با این حال، ما یک مشکل مفهومی داریم. همانطور که ممکن است به خاطر داشته باشید، یکی از مزایای اصلی OOP این است که مدل سازی موجودیت های دنیای واقعی را آسان می کند. یک صندلی، یک ماشین، یک سیاره - همه این مفاهیم از زندگی روزمره به راحتی در یک برنامه با استفاده از انتزاع نمایش داده می شوند. مشکل این است که برخی از موجودات در دنیای واقعی دارای طیف محدودی از معانی هستند. در سال فقط 4 فصل وجود دارد. تنها 7 نت در موسیقی وجود دارد. فقط 12 ماه در تقویم وجود دارد. Ocean فقط 11 دوست دارد (اگرچه این موضوع قابل بحث است :)) به عبارت دیگر، یک کلاس جاوای معمولی قادر به مدل سازی این موجودیت ها و رعایت محدودیت های طبیعی آنها نیست. کلاس ما Monthتمام زمینه های لازم را دارد. اما اگر برنامه نویس دیگری از آن استفاده کند، هیچ کس او را از ایجاد اشیاء کاملاً دیوانه منع نمی کند:
public class Main {

   Month month1 = new Month("lolkek", 322);
   Month month2 = new Month("yahoooooooooooo", 12345);

}
اگر این در برنامه ظاهر شود، پیدا کردن مقصر کار آسانی نخواهد بود! از یک طرف، برنامه نویسی که این اشیاء را ایجاد کرد می توانست بفهمد که کلاس Monthبه معنای "ماه سال" است و چنین مزخرفاتی را ننویسد. از طرفی فقط از فرصت هایی که طراح کلاس در اختیارش قرار داده بود استفاده می کرد. آیا می توانم نام و تعداد روز را تعیین کنم؟ منصوبش کرد. در چنین شرایطی چه باید کرد؟ قبل از انتشار نسخه 1.5 زبان جاوا، برنامه نویسان مجبور بودند، صادقانه بگویم، از آن خارج می شدند :) در آن روزها، ساختارهای زیر را ایجاد کردند:
public class Month {

   private String name;
   private int daysCount;

   private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public static Month JANUARY = new Month("Январь", 31);
   public static Month FEBRUARY = new Month("Февраль", 28);
   public static Month MARCH = new Month("Март", 31);

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
در اینجا ما تعداد ماه ها را به جای دوازده به سه ساده کرده ایم تا مثال کوتاهتر باشد. چنین طرح هایی حل مشکل را ممکن می کرد. گزینه های مربوط به اشیاء ایجاد شده توسط یک سازنده خصوصی محدود شد:
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
برنامه نویسانی که از کلاس استفاده می کنند نمی توانند به سادگی ایجاد کنند Month. آنها مجبور شدند از آن اشیاء استاتیک نهایی که توسط توسعه دهنده کلاس ارائه شده بود استفاده کنند. چیزی شبیه این به نظر می رسید:
public class Main {

   public static void main(String[] args) {

       Month january = Month.JANUARY;
       System.out.println(january);
   }

}
با این حال، توسعه دهندگان جاوا متوجه یک مشکل موجود شده اند. البته، خیلی خوب است که برنامه نویسان توانستند با استفاده از ابزارهای موجود در زبان راه حلی ارائه دهند، اما به نظر ساده نمی رسد! یک راه حل واضح مورد نیاز بود که حتی برای مبتدیان قابل دسترسی بود. اینگونه در جاوا ظاهر شد Enum. اساساً Enumیک کلاس جاوا است که مجموعه محدودی از اشیاء با ارزش را ارائه می دهد. در اینجا به نظر می رسد:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
در تعریف نشان دادیم که Enumاین یک کلاس جاوا است، اما آیا این واقعاً درست است؟ بله، و ما حتی می توانیم آن را بررسی کنیم. برای مثال سعی کنید کلاس ما را enum Monthاز کلاس دیگری به ارث ببرید:
public abstract class AbstractMonth {
}

//ошибка! No extends clause allowed to enum
public enum Month extends AbstractMonth {

   JANUARY,
   FEBRUARY,
   MARCH
}
چرا این اتفاق می افتد؟ وقتی برای یک برنامه می نویسیم:
public enum Month
کامپایلر این دستور را به کد زیر تبدیل می کند:
public Class Month extends Enum
همانطور که می دانید، وراثت چندگانه در جاوا مجاز نیست. بنابراین، AbstractMonthما نمی توانستیم از آن ارث ببریم. چگونه می توان از این طرح جدید Enumاستفاده کرد؟ و چه تفاوتی با طرح قدیمی با static finalفیلد دارد؟ خوب، به عنوان مثال، طراحی قدیمی به ما اجازه نمی داد از مجموعه مقادیر خودمان در switchعبارات استفاده کنیم. تصور کنید که می خواهیم برنامه ای ایجاد کنیم که به ما یادآوری کند که چه تعطیلاتی در این ماه جشن گرفته می شود:
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
در اینجا همانطور که می بینید کامپایلر خطا می دهد. اما پس از ظاهر شدن جاوا 1.5 enum، همه چیز بسیار ساده تر شد:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}

public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           case JANUARY:
               System.out.println("7 января будет Рождество!");
               break;
           case FEBRUARY:
               System.out.println("В феврале празднуется День Защитника Отечества - 23 февраля!");
               break;
           case MARCH:
               System.out.println("В марте отмечается Всемирный Женский День - 8 марта!");
               break;
       }
   }
}



public class Main {

   public static void main(String[] args) {

       HolidayReminder reminder = new HolidayReminder();
       reminder.printHolidays(Month.JANUARY);

   }

}
خروجی کنسول:

7 января будет Рождество!
لطفا توجه داشته باشید: دسترسی به اشیا Enumمانند قبل از جاوا 1.5 ثابت باقی می ماند. برای دسترسی به ماه ها نیازی به ایجاد یک شیء نداریم Month. هنگام کار با شمارش، بسیار مهم است که فراموش نکنید که Enumاین یک کلاس تمام عیار است. یعنی در صورت لزوم می توانید سازنده ها و متدهایی را در آن تعریف کنید. به عنوان مثال، در کد قبلی به سادگی مقادیر JANUARY، FEBRUARY، MARCH را مشخص کردیم. با این حال، ما می توانیم خدمات خود را enum Monthبه این صورت گسترش دهیم:
public enum Month {

   JANUARY("Январь", 31),
   FEBRUARY("Февраль", 28),
   MARCH("Март", 31),
   APRIL("Апрель", 30),
   MAY("Май", 31),
   JUNE("Июнь", 30),
   JULY("Июль", 31),
   AUGUST("Август", 31),
   SEPTEMBER("Сентябрь", 30),
   OCTOBER("Октябрь", 31),
   NOVEMBER("Ноябрь", 30),
   DECEMBER("Декабрь", 31);

   private String name;
   private int daysCount;

   Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public static Month[] getWinterMonths() {

       return new Month[]{DECEMBER, JANUARY, FEBRUARY};
   }

   public static Month[] getSummerMonths() {

       return new Month[]{JUNE, JULY, AUGUST};
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getDaysCount() {
       return daysCount;
   }

   public void setDaysCount(int daysCount) {
       this.daysCount = daysCount;
   }

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
در اینجا ما 2 فیلد را به فیلد خود اضافه کرده ایم enum- نام ماه و تعداد روزها، سازنده ای که از این فیلدها استفاده می کند، گیرنده-ستترها، یک متد toString()و همچنین 2 روش استاتیک. همانطور که می بینید، هیچ مشکلی در این مورد وجود نداشت: همانطور که قبلاً گفتیم، enumاین یک کلاس تمام عیار است:
import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

       System.out.println(Arrays.toString(Month.getSummerMonths()));

   }

}
خروجی کنسول:

[Month{name='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
در نهایت، می‌خواهم یک کتاب بسیار مفید در مورد جاوا را به شما توصیه کنم، یعنی «جاوای مؤثر» اثر جاشوا بلوخ . Enum.  نمونه های عملی  افزودن سازنده ها و روش ها - 3نویسنده یکی از سازندگان جاوا است، بنابراین شما قطعا می توانید به توصیه های او در مورد استفاده صحیح و شایسته از ابزارهای زبان اعتماد کنید :) در رابطه با سخنرانی ما، به شما توصیه می کنم به فصل کتاب که به enum. خواندن سازنده داشته باشید! :)
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION