JavaRush /مدونة جافا /Random-AR /التعداد في جافا: كيفية استخدام الفصل

التعداد في جافا: كيفية استخدام الفصل

نشرت في المجموعة
مرحبًا! في هذه المقالة سأخبرك عن Java Enums. تخيل أنه تم تكليفك بمهمة: إنشاء فصل دراسي يقوم بتنفيذ أيام الأسبوع . للوهلة الأولى، لا يوجد شيء معقد في هذا الأمر، وسيبدو الكود الخاص بك كما يلي:
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 . بهذه الطريقة، يمكن لأي شخص إنشاء يوم من أيام الأسبوع "Frog" أو "Cloud" أو "azaza322". من الواضح أن هذا ليس السلوك الذي نتوقعه، لأن هناك 7 أيام حقيقية فقط في الأسبوع، ولكل منها اسم. ولذلك، فإن مهمتنا هي الحد بطريقة أو بأخرى من نطاق القيم الممكنة لفئة " يوم من الأسبوع ". قبل 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 + '\'' +
               '}';
   }
}
ما يجب الانتباه إليه هنا:
  • منشئ خاص. إذا تم وضع علامة على المُنشئ باستخدام المُعدِّل الخاص ، فلا يمكن إنشاء كائن من الفئة باستخدام هذا المُنشئ. وبما أن هناك منشئًا واحدًا فقط في هذه الفئة، فلا يمكن إنشاء كائن DayOfWeek على الإطلاق.

    public class Main {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = new DayOfWeek();//error!
       		}
    }
  • في الوقت نفسه، يحتوي الفصل على العدد المطلوب من الكائنات الثابتة العامة التي تمت تهيئتها بالطريقة التي نحتاجها (أسماء الأيام صحيحة).

    هذا جعل من الممكن استخدام الكائنات في فئات أخرى.

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

    خاتمة:

    يومالأسبوع{title='الأحد'}

هذا النهج سمح لنا إلى حد كبير بحل المشكلة. كان لدينا 7 أيام في الأسبوع تحت تصرفنا، ولم يتمكن أحد من إنشاء أيام جديدة. تم اقتراح هذا الحل بواسطة جوشوا بلوخ في كتاب جافا الفعالة . الكتاب، بالمناسبة، رائع جدًا ويجب قراءته لأي مطور جافا.
كيفية استخدام فئة التعداد - 2
مع إصدار Java 1.5، قدمت اللغة حلاً جاهزًا لمثل هذه المواقف - التعداد التعدادي . التعداد هو أيضا فئة. ولكنها "مصممة" خصيصًا لحل المشكلات المشابهة لمشاكلنا: إنشاء نطاق محدود معين من القيم. نظرًا لأن منشئي Java كان لديهم بالفعل أمثلة جاهزة (على سبيل المثال، لغة C التي يوجد بها Enum بالفعل)، فقد تمكنوا من إنشاء الخيار الأمثل.

ما هو التعداد؟

إذن ما هو التعداد في جافا ؟ دعونا نلقي نظرة على مثال DayOfWeek نفسه :
public enum DayOfWeek {

   SUNDAY,
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY
}
يبدو بالفعل أبسط بكثير :) يوجد داخل التعداد الخاص بنا 7 ثوابت ذات وصول ثابت. يمكننا بالفعل استخدامه لتنفيذ المنطق في البرنامج. على سبيل المثال، لنكتب برنامجًا يحدد ما إذا كان الطالب بحاجة للذهاب إلى المدرسة اليوم. سيكون لطالبنا روتين يومي خاص به، يحدده فصل ScholarSchedule :
public class ScholarSchedule {

   private DayOfWeek dayOfWeek;
   //...other fields


   public DayOfWeek getDayOfWeek() {
       return dayOfWeek;
   }

   public void setDayOfWeek(DayOfWeek dayOfWeek) {
       this.dayOfWeek = dayOfWeek;
   }
}
يحدد المتغير dayOfWeek في وضع اليوم ما هو اليوم. وهنا فصل طلابنا:
public class Scholar {

   private ScholarSchedule schedule;
   private boolean goToSchool;

   public void wakeUp() {

       if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
           System.out.println("Hooray, you can sleep some more!");
       } else {
           System.out.println("Damn, back to school :(");
       }
   }
}
في طريقة WakeUp() ، باستخدام Enum، نحدد الإجراءات الإضافية للطالب. لم نوضح حتى بالتفصيل ما يعنيه كل متغير في DayOfWeek ، وهذا ليس ضروريًا: آلية أيام الأسبوع واضحة بالفعل، وإذا استخدمناها في شكلها الحالي، فإن أي مطور سيفهم ما يحدث في التعليمات البرمجية الخاصة بك. مثال آخر على سهولة استخدام Enum هو إمكانية استخدام ثوابته مع عبارة التبديل . على سبيل المثال، نقوم بكتابة برنامج لنظام غذائي صارم، يتم فيه جدولة الوجبات حسب اليوم:
public class VeryStrictDiet {
   public void takeLunch(DayOfWeek dayOfWeek) {
       switch (dayOfWeek) {
           case SUNDAY:
               System.out.println("Sunday lunch! Today you can even have a little sweet");
               break;
           case MONDAY:
               System.out.println("Monday Lunch: Chicken Noodles!");
               break;
           case TUESDAY:
               System.out.println("Tuesday, today is celery soup :(");
               break;
               //...and so on until 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 لدينا الآن على حقل عنوان ، وحرف getter، وطريقة toString التي تم تجاوزها . بالمقارنة مع الفصول العادية، لدى Enum قيد واحد خطير - لا يمكن توريثه. بالإضافة إلى ذلك، للتعدادات طرق فريدة خاصة بها:
  • values() : تقوم بإرجاع مصفوفة من كافة القيم المخزنة في Enum :

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

    خاتمة:

    [DayOfWeek{title='Sunday'}, DayOfWeek{title='Monday'}, DayOfWeek{title='Tuesday'}, DayOfWeek{title='Wednesday'}, DayOfWeek{title='Thursday'}, DayOfWeek{title= 'الجمعة'}، DayOfWeek{title='Saturday'}]

  • 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);
    }

    خاتمة:

    يومالأسبوع{title='الأحد'}

انتبه:نقوم بتكبير أسماء عناصر Enum لأنها ثوابت ويتم تحديدها كثوابت، وليس CamelCase .
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION