دوال التوسعة
جزء من قسم البرمجة كائنية التوجه في رحلة Kotlin على Coddy. الدرس 30 من 57.
تضيف دالة الامتداد دالةً إلى نوع موجود من دون تغيير الشيفرة المصدرية للنوع. يُكتب اسمها بعد نوع المُستقبِل، وداخلها تشير this إلى المُستقبِل، ويمكن أيضًا حذفها:
fun String.shout() = uppercase() + "!"
fun Int.isEven() = this % 2 == 0داخل main:
println("hello".shout())
println(7.isEven())
println(listOf(1, 2, 3, 4).count { it.isEven() })الناتج:
HELLO!
false
2تعمل الامتدادات مع أصنافك الخاصة أيضًا، وتضيف خصائص الامتداد خصائص محسوبة. لا يمكن للامتداد إضافة حالة مخزّنة، ولا يصل إلا إلى الأعضاء العامة للمستقبِل:
class Temperature(val celsius: Double)
val Temperature.fahrenheit: Double
get() = celsius * 9 / 5 + 32
fun Temperature.describe() = "$celsius C is $fahrenheit F"داخل main:
println(Temperature(100.0).describe())الناتج:
100.0 C is 212.0 Fيتم تحليل الامتدادات بشكل ثابت: يحدد النوع المُعلَن للتعبير الامتدادَ عند تجميع البرنامج، وليس فئة الكائن. وهذا هو الفرق الرئيسي عن عضو تمت إعادة تعريفه:
open class Shape {
open fun member() = "shape member"
}
class Circle : Shape() {
override fun member() = "circle member"
}
fun Shape.ext() = "shape extension"
fun Circle.ext() = "circle extension"داخل main:
val s: Shape = Circle()
println(s.member())
println(s.ext())الناتج:
circle member
shape extensionعندما يكون لدى الفئة عضو بالتوقيع نفسه بالفعل، يفوز العضو دائمًا. استخدم الأعضاء للسلوك الذي ينتمي إلى النوع والذي قد تتم إعادة تعريفه؛ واستخدم الامتدادات للمساعدات المُضافة من الخارج، مثل التنسيق لفئة لا تملكها:
class Robot {
fun greet() = "member greet"
}
fun Robot.greet() = "extension greet"
fun Robot.wave() = "extension wave"داخل main:
val r = Robot()
println(r.greet())
println(r.wave())الناتج:
member greet
extension waveالتحدي
سهليتم توفير Money(cents) في Money.kt. اكتب الامتدادات الخاصة به في MoneyExtensions.kt: خصائص الامتداد Int.dollars وInt.cents، اللتان تحولان رقمًا إلى Money (حيث إن 12.dollars تساوي 1200 سنت)، وMoney.format()، التي تُرجع $12.50 (أو -$3.05 للمبالغ السالبة)، وList<Money>.total()، التي تُرجع المجموع كقيمة من نوع Money، وMoney.split(parts)، التي تقسّم المبلغ إلى parts من القيم التي يختلف بعضها عن بعض بمقدار سنت واحد على الأكثر، مع وضع القيم الأكبر أولًا.
يقرأ الكود المقدم أسطرًا مثل 12 dollars أو 50 cents، وسطرًا أخيرًا يحتوي على عدد الأجزاء. ويطبع كل مبلغ، ثم total: $12.50 وsplit 3: $4.17 $4.17 $4.16.
يجب وضع كودك في MoneyExtensions.kt وMoney.kt. يحتوي Main.kt على كود الإدخال/الإخراج المقدم، ولا يمكن تعديله.
جرّب بنفسك
fun main() {
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
val input = generateSequence(::readLine).toList()
val amounts = input.dropLast(1).map { line ->
val (n, unit) = line.split(" ")
if (unit == "dollars") n.toInt().dollars else n.toInt().cents
}
for (m in amounts) println(m.format())
val total = amounts.total()
println("total: ${total.format()}")
val parts = input.last().toInt()
println("split $parts: " + total.split(parts).joinToString(" ") { it.format() })
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتالمنشئات الأساسيةكتل init والتحقق من الصحةالمنشئات الثانويةمراجعة - بطاقة المكتبة4الوراثة
الأصناف المفتوحة والأصناف الفرعيةتجاوز الأعضاءsuper والمنشئاتالأصناف المجرّدةمراجعة - دليل الموظفين3الكائنات والكائنات المرافقة
تعريفات الكائناتالكائنات المرافقةالثوابت باستخدام constتعبيرات الكائناتمراجعة - شباك التذاكر6تعدد الأشكال
التوجيه الديناميكيفحوصات الأنواع والتحويلات الذكيةwhen مع الأنواعدوال التوسعةمراجعة - حارس حديقة الحيواناتتدرّب بنفسك: Playground لـ Kotlin