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 أيام حقيقية فقط في الأسبوع، ولكل منها اسم محدد. ولذلك، فإن مهمتنا هي تحديد نطاق القيم الممكنة لفئة 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 + '\'' +
'}';
}
}
إليك ما يجب أن تلاحظه:
-
المنشئ خاص. إذا تم وضع علامة على المنشئ باستخدام المعدل الخاص ، فلا يمكن استخدامه لإنشاء كائن. وبما أن الفصل يحتوي على مُنشئ واحد فقط، فلا يمكن إنشاء كائنات 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 = 'الأحد'}
إذن ما هو Java Enum؟
دعنا نعيد النظر في مثال DayOfWeek الخاص بنا :public enum DayOfWeek {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
الآن يبدو الأمر أبسط بكثير :) داخليًا، يحتوي Enum الخاص بنا على 7 ثوابت ثابتة. وهذا شيء يمكننا استخدامه لتنفيذ البرنامج. على سبيل المثال، لنكتب برنامجًا يحدد ما إذا كان الطالب بحاجة للذهاب إلى المدرسة اليوم. سيكون لدى طلابنا جدول يومي، يمثله فصل 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 لتحديد ما يجب على الطالب فعله بعد ذلك. لم نقدم حتى تفاصيل حول كل حقل في DayOfWeek ، ولسنا بحاجة إلى ذلك: من الواضح كيف من المفترض أن تعمل أيام الأسبوع. إذا استخدمناها في شكلها الحالي، فإن أي مطور سيفهم ما يحدث في الكود الخاص بنا. مثال آخر على سهولة استخدام Enum هو إمكانية استخدام ثوابته مع عبارة التبديل. على سبيل المثال، دعونا نكتب برنامجًا لنظام غذائي صارم، حيث يتم جدولة الأطباق يوميًا:
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
}
}
}
هذه إحدى ميزات Enums مقارنة بالحل القديم المستخدم قبل 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 - لا يمكن توريثها. بالإضافة إلى ذلك، للتعدادات طرق مميزة:
-
value() : تُرجع مصفوفة من كافة القيم الموجودة في 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); }
انتاج:
DayOfWeek{title = 'الأحد'}
المزيد من القراءة: |
---|
GO TO FULL VERSION