الأساليب الافتراضية
جزء من قسم البرمجة كائنية التوجه في رحلة 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التحدي
سهلتحتوي الواجهة 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"}")
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتالمنشئات الأساسيةكتل init والتحقق من الصحةالمنشئات الثانويةمراجعة - بطاقة المكتبة4الوراثة
الأصناف المفتوحة والأصناف الفرعيةتجاوز الأعضاءsuper والمنشئاتالأصناف المجرّدةمراجعة - دليل الموظفينتدرّب بنفسك: Playground لـ Kotlin