أصناف الثوابت المُتعدِّدة (Enum Classes) في لغة Kotlin
يتلخَّصُ الاستخدام الرئيسيّ لأصناف الثوابت المتعدَّدة في قدرتها على تعريف الاستخدام (implementing) للثوابت المتعدًّدة الحافظة للنوع (type-safe)، ,ويُصرَّح عنها بالشكل:
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
إذ يُعدُّ كلُّ ثابتٍ فيها كائنًا (object)، ويُفصل فيما بينها بالفاصلة ,
.
التهيئة (Initialization)
بما أن كلّ ثابتٍ في صنف الثوابت المتعدِّدة (enum) يُعدُّ كائنًا فيمكن إجراء التهيئة كما يلي:
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}
الأصناف المجهولة (Anonymous Classes)
يُتاح لأيّ ثابتٍ معرَّفٍ في صنف الثوابت المتعدِّدة (enum class) تعريفُ الأصناف المجهولة الخاصّة به، مثل الشيفرة الآتية:
enum class ProtocolState {
WAITING {
override fun signal() = TALKING
},
TALKING {
override fun signal() = WAITING
};
abstract fun signal(): ProtocolState
}
إذ يحتوي كلُّ صنفٍ مجهولٍ منها على التوابع المُوافقة وإعادة تعريفٍ (override) للتوابع الأساسيّة، وإذا احتوى صنف الثوابت المتعدِّدة (enum) على أيّة عناصر (members) أخرى فيجب الفصل ما بين تعريف الثوابت بأجمعها وتعريف العناصر الأخرى في الصنف بفاصلةٍ منقوطةٍ ;
كما هو الحال في Java، ولا يمكن أن تحتوي أصناف الثوابت المتعدِّدة على أي عناصر داخلها إلا الأصناف الداخليّة (inner classes) وهذا بحدِّ ذاته مُستبعد في الإصدار Kotlin 1.2.
التعامل مع الثوابت المتعدِّدة (Enum)
تحتوي أصناف الثوابت المتعدِّدة (enum) في Kotlin على توابع تركيبية (synthetic methods) -كما هو في Java- مما يسمح بتعداد الثوابت المُتعدِّدة والوصول إلى أيّ ثابتٍ منها عبر اسمه، وتكون ترويسة هذه التوابع كما يلي: (بفرض أنّ اسم صنف الثوابت المتعدِّدة هو EnumClass
)
EnumClass.valueOf(value: String): EnumClass
EnumClass.values(): Array<EnumClass>
إذ إنّ التابع valueOf()
سيعطي استثناءً من النوع IllegalArgumentException
إذا لم يتوافق الاسم المُحدَّد مع أيّ من أسماء الثوابت المعرًّفة في الصنف.
وأُتيح بدءًا من الإصدار Kotlin 1.1 الوصول إلى الثوابت المتعدَّدة في صنفها (enum) بطريقة مُعمَّمة (generic) بالاعتماد على الدالتين enumValues<T>()
و enumValueOf<T>()
، كما في الشيفرة الآتية:
enum class RGB { RED, GREEN, BLUE }
inline fun <reified T : Enum<T>> printAllValues() {
print(enumValues<T>().joinToString { it.name })
}
printAllValues<RGB>() // ستظهر العبارة RED, GREEN, BLUE
ويحتوي كلّ من هذه الثوابت على خاصّيّاتٍ (properties) للحصول على اسمه وترتيبه ضمن تعريف الصنف، وهي بالشكل:
val name: String
val ordinal: Int
وتحتوي الثوابت أيضًا على تعريف استخدام (implementation) الواجهة Comparable
وبالترتيب الذي رُتِّبَت فيه في صنف الثوابت المتعدِّدة (enum).