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

الأساليب الافتراضية

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

يمكن أن تحتوي دالة الواجهة على جسم. يُستخدم هذا التنفيذ الافتراضي من قِبل كل فئة لا تتجاوزه:

interface Greeter {
    val name: String
    fun greet() = "Hello, I am $name"
}
class Robot(override val name: String) : Greeter
class Pirate(override val name: String) : Greeter {
    override fun greet() = "Ahoy! $name here"
}

داخل main:

println(Robot("R2").greet())
println(Pirate("Anne").greet())

الناتج:

Hello, I am R2
Ahoy! Anne here

تُكتب الطرق الافتراضية باستخدام الأعضاء الآخرين للواجهة. ويوفّر الصنف الأعضاء القليلة المختلفة، ويحصل على البقية:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
    fun isAffordable(budget: Int) = cents <= budget
}
class Coffee : Priced {
    override val cents = 450
}

داخل main:

val c = Coffee()
println(c.formatted())
println(c.isAffordable(400))

الناتج:

$4.50
false

يمكن أن تحتوي الخصائص على مُلحق وصول افتراضي، لكن الواجهة لا تحتوي على حقول داعمة، لذا لا يمكنها تخزين قيمة. لا يتم تجميع الخاصية التي تحتوي على مُهيّئ؛ بينما يتم تجميع مُلحق وصول يحسب القيمة:

interface Box {
    val width: Int
    val height: Int
    val area: Int
        get() = width * height
    // val count = 0      // error: مهيئات الخصائص غير مسموح بها في الواجهات
}
class Tile(override val width: Int, override val height: Int) : Box

داخل main:

println(Tile(3, 4).area)

الناتج:

12

يمكن للتجاوز أن يستخدم التنفيذ الافتراضي أيضًا. داخل الفئة، يستدعي super.method() إصدار الواجهة:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
}
class Coffee : Priced {
    override val cents = 450
    override fun formatted() = "coffee " + super.formatted()
}

داخل main:

println(Coffee().formatted())

الناتج:

coffee $4.50
challenge icon

التحدي

سهل

تحتوي الواجهة Priced على price (بالسنتات). امنحها دالة افتراضية formatted() تُرجع $4.50، ودالة افتراضية isAffordable(budget) تُرجع ما إذا كان السعر لا يتجاوز الميزانية. تبلغ تكلفة Coffee مقدار 450، وتستبدل formatted() بالقيمة coffee $4.50، مع إعادة استخدام القيمة الافتراضية من خلال super. يستخدم Sandwich(price) القيمتين الافتراضيتين.

يقرأ الكود المقدم ميزانيةً بالسنتات، ثم يقرأ أسطرًا تحتوي على coffee أو sandwich,650. ويطبع formatted() وyes أو no لكل عنصر.

ضع الكود الخاص بك في Priced.kt وCoffee.kt وSandwich.kt. يحتوي Main.kt على كود الإدخال/الإخراج المقدم، ولا يمكن تعديله.

جرّب بنفسك

fun main() {
    // كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
    val input = generateSequence(::readLine).toList()
    val budget = input[0].toInt()
    for (line in input.drop(1)) {
        val p = line.split(",")
        val item: Priced = if (p[0] == "coffee") Coffee() else Sandwich(p[1].toInt())
        println("${item.formatted()} ${if (item.isAffordable(budget)) "yes" else "no"}")
    }
}
quiz iconاختبر نفسك

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

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

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