Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

دوال وصول مخصصة

جزء من قسم البرمجة كائنية التوجه في رحلة Kotlin على Coddy. الدرس 7 من 57.

كل خاصية في Kotlin لها دالة getter، وكل var لها أيضًا دالة setter. افتراضيًا، تقومان بقراءة قيمة مخزّنة وكتابتها. أما دالة getter مخصّصة فتحسب القيمة عند كل عملية قراءة بدلًا من ذلك:

class Rectangle(var width: Int, var height: Int) {
    val area: Int
        get() = width * height
}

داخل main:

val r = Rectangle(3, 4)
println(r.area)
r.width = 10
println(r.area)

الناتج:

12
40

يُشغِّل المُعيِّن المخصّص تعليمات برمجية كلما أُسنِدت قيمة إلى الخاصية. بداخله، value هي القيمة المُسنَدة وfield هي القيمة المخزَّنة وراء الخاصية، أي الحقل الداعم:

class Thermostat {
    var target = 20
        set(value) {
            field = value.coerceIn(10, 30)
        }
}

داخل main:

val t = Thermostat()
t.target = 42
println(t.target)
t.target = 18
println(t.target)

الناتج:

30
18

داخل أداة الوصول، استخدم field، وليس اسم الخاصية: كتابة target = value داخل أداة التعيين للخاصية target ستستدعي أداة التعيين مرة أخرى، إلى ما لا نهاية:

var target = 20
    set(value) {
        // target = value        // يستدعي هذا الـ setter مرة أخرى: تكرار لانهائي
        field = value             // يخزن القيمة
    }

يُعدّ setter أيضًا المكان المناسب للتفاعل مع التغييرات، مثل عدّها أو تسجيلها:

class Player(name: String) {
    var changes = 0
        private set
    var name = name
        set(value) {
            field = value.trim()
            changes++
        }
}

داخل main:

val p = Player("ada")
p.name = "  Ada  "
p.name = "Ada L."
println("${p.name} after ${p.changes} changes")

الناتج:

Ada L. after 2 changes
challenge icon

التحدي

سهل

أكمل الصنف Circle(radius: Double). ‏radius هو var يخزّن القيم السالبة على أنها 0. أضف الخاصيتين للقراءة فقط diameter وarea ‏(π r² باستخدام Math.PI) مع دوال وصول مخصّصة، وأضف label، الذي يعيد r=2.0 d=4.0 a=12.57 مع تقريب المساحة إلى منزلتين عشريتين ‏("%.2f".format(area)).

يقرأ الكود المزوّد نصف قطر واحدًا في كل سطر، ويطبع label، ثم يضاعف نصف قطر الدائرة الأخيرة ويطبع label مرة أخرى، لذا يجب أن تتبع القيم نصف القطر.

ضع كودك في Circle.kt. يحتوي Main.kt على كود الإدخال/الإخراج المزوّد، ولا يمكن تعديله.

جرّب بنفسك

fun main() {
    // كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
    val input = generateSequence(::readLine).toList()
    var last = Circle(0.0)
    for (line in input) {
        last = Circle(line.toDouble())
        println(last.label)
    }
    last.radius *= 2
    println(last.label)
}
quiz iconاختبر نفسك

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

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

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