Menu
CoddyTech

تعريفات الكائنات

جزء من قسم البرمجة كائنية التوجه في رحلة 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()           // خطأ: الكائن ليس له مُنشئ
challenge icon

التحدي

سهل

أكمل الكائن 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}")
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: Playground لـ Kotlin