تعريفات الكائنات
جزء من قسم البرمجة كائنية التوجه في رحلة Kotlin على Coddy. الدرس 12 من 57.
object Name { ... } يصرّح عن صنف ونسخته الوحيدة في خطوة واحدة. تستخدم الكائن باسمه؛ ولا يوجد مُنشئ لاستدعائه:
object AppConfig {
var theme = "light"
val version = "1.4"
fun describe() = "v$version, $theme theme"
}داخل main:
println(AppConfig.describe())
AppConfig.theme = "dark"
println(AppConfig.describe())الناتج:
v1.4, light theme
v1.4, dark themeيوجد مثيل واحد تمامًا، لذلك فإن كل جزء من البرنامج يستخدم الكائن يقرأ الحالة نفسها ويغيّرها. يُنشأ الكائن عند استخدامه لأول مرة، كما توضّح كتلة init أدناه:
object Visits {
var count = 0
private set
init { println("Visits created") }
fun record() { count++ }
}
fun home() = Visits.record()
fun about() { Visits.record(); Visits.record() }داخل main:
println("start")
home()
about()
println(Visits.count)الناتج:
start
Visits created
3لا يحتوي الكائن على مُنشئ، لأن لا أحد ينشئه. تحصل خصائصه على قيمها في تصريحاتها أو في init. وبخلاف ذلك، فهو جسم فئة عادي: حالة خاصة، ودوال مساعدة خاصة، وطرائق عامة:
object IdGenerator {
private var next = 1
fun newId(prefix: String) = "$prefix-${pad(next++)}"
private fun pad(n: Int) = n.toString().padStart(3, '0')
}داخل main:
println(IdGenerator.newId("user"))
println(IdGenerator.newId("order"))الناتج:
user-001
order-002استخدم كائنًا لشيء يوجد منه مثيل واحد بالضبط في البرنامج: سجل، أو الإعدادات، أو مجموعة من الدوال المساعدة. الكائن هو حالة عامة يمكن لأي ملف تغييرها، لذا اجعل دوال ضبطها خاصة، ودع أساليبه تتحقق من كل تغيير.
object Units {
fun kmToMiles(km: Double) = km * 0.621371
}
Units.kmToMiles(10.0) // يُستدعى من خلال الاسم
// val u = Units() // خطأ: الكائن ليس له منشئالتحدي
سهلأكمل الكائن Leaderboard. يحتفظ بنقاط كل لاعب في خريطة خاصة. تضيف add(player, points) النقاط، وتُرجع top() المتصدرَ بالشكل ada 6 (عند تساوي النقاط، يُختار الاسم الذي يأتي أولًا أبجديًا) أو empty عندما لا يملك أحد نقاطًا، وتزيل reset() الجميع، أما الخاصية players فهي عدد اللاعبين.
الدالتان المساعدتان recordWin وrecordDraw في Functions.kt مُقدَّمتان؛ وهما تستخدمان Leaderboard من ملف آخر. يقرأ الكود المُقدَّم الأوامر win ada أو draw ada bo أو top أو reset، ويطبع top() لكل أمر top، ثم يطبع أخيرًا players: مع العدد.
ضع كودك في Leaderboard.kt وFunctions.kt. يحتوي Main.kt على كود الإدخال/الإخراج المُقدَّم، ولا يمكن تعديله.
جرّب بنفسك
fun main() {
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
val input = generateSequence(::readLine).toList()
for (cmd in input) {
val p = cmd.split(" ")
when (p[0]) {
"win" -> recordWin(p[1])
"draw" -> recordDraw(p[1], p[2])
"reset" -> Leaderboard.reset()
else -> println(Leaderboard.top())
}
}
println("players: ${Leaderboard.players}")
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتالمنشئات الأساسيةكتل init والتحقق من الصحةالمنشئات الثانويةمراجعة - بطاقة المكتبة4الوراثة
الأصناف المفتوحة والأصناف الفرعيةتجاوز الأعضاءsuper والمنشئاتالأصناف المجرّدةمراجعة - دليل الموظفين3الكائنات والكائنات المرافقة
تعريفات الكائناتالكائنات المرافقةالثوابت باستخدام constتعبيرات الكائناتمراجعة - شباك التذاكرتدرّب بنفسك: Playground لـ Kotlin