الامتدادات ذات النطاق وامتدادات companion
قيّد مستوى ظهور الامتدادات وأضف امتدادات إلى companion objects.
الامتدادات ذات النطاق وامتدادات companion درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
لماذا نستخدم الامتدادات ذات النطاق؟
تكون الامتدادات مرئية افتراضيًا أينما تم استيرادها. ويحدّ النطاق من الرؤية لتقتصر على فئة أو ملف أو سياق، مما يقلل تلوث مساحة الأسماء ويحسّن سهولة العثور عليها.
امتدادات خاصة بالملف
ضعوا علامة private على دالة امتداد على مستوى الملف لتقتصر على ذلك الملف فقط.
private fun String.shout() = uppercase() + "!"
fun main() {
println("hello".shout()) // HELLO!
}الرؤية الداخلية
استخدموا internal لحصر الامتدادات في الوحدة الحالية، وهو أمر مثالي للأجزاء الداخلية من المكتبة التي لا يُقصد استخدامها خارجيًا.
internal fun List<Int>.sumIfPositive(): Int = filter { it > 0 }.sum()
fun main() {
println(listOf(-1, 2, 3, -4).sumIfPositive()) // 5
}دوال امتداد الأعضاء
صرّحوا عن امتداد داخل فئة لجعله قابلًا للاستخدام فقط عندما يكون مثيل من تلك الفئة ضمن النطاق. وله مستقبلان: مستقبل التوزيع (الفئة) ومستقبل الامتداد (الهدف).
class StringHelper(val prefix: String) {
fun String.withPrefix() = prefix + this
fun build(): String = "world".withPrefix() // calls extension via instance
}
fun main() {
println(StringHelper("hello ").build()) // hello world
}رؤية امتدادات الأعضاء
لا يمكن الوصول إلى امتدادات الأعضاء من خارج فئة التوزيع. وهذا مفيد للتغليف.
class Repo {
fun List<Int>.allPositive() = all { it > 0 }
fun check(xs: List<Int>) = xs.allPositive()
}
fun main() {
val r = Repo()
println(r.check(listOf(1, 2, 3))) // true
// listOf(1).allPositive() // ERROR — no access
}الامتداد على الكائن المرافق
أضيفوا امتدادًا إلى الكائن المرافق لفئة. وسيبدو كأنه دالة static للمتصلين، لكنه يوجد خارج الفئة.
class Greeter {
companion object
}
fun Greeter.Companion.morning() = "Good morning!"
fun main() {
println(Greeter.morning())
}لماذا نستخدم امتدادات الكائنات المرافقة؟
تُعد مفيدة لإضافة دوال مُنشئة أو أدوات مساعدة من خارج الفئة الأصلية، دون تعديلها.
class User(val name: String) {
companion object
}
fun User.Companion.guest() = User("Guest")
fun User.Companion.system() = User("System")
fun main() {
println(User.guest().name)
println(User.system().name)
}يلزم وجود كائن مرافق فارغ
يجب أن تصرّح الفئة عن كائن مرافق (حتى لو كان فارغًا) كي ترتبط به امتدادات الكائن المرافق. وإلا فلن يكون هدف الامتداد موجودًا.
class Box {
companion object // required, even if empty
}
fun Box.Companion.create(): Box = Box()
fun main() {
println(Box.create())
}الامتدادات ذات النطاق عبر الاستيراد
يمكنكم حصر استخدام امتداد باستيراده في ملفات محددة فقط. ولن تتمكن الملفات التي لا تستورده من رؤيته.
// File A:
// fun String.shout() = uppercase()
// File B imports:
// import com.example.shout
// Only File B can call shout()
fun String.shout() = uppercase() + "!"
fun main() { println("hi".shout()) }دالة امتداد عبر دالة نطاق
استخدموا with أو apply لإدخال كائن مؤقتًا إلى النطاق لاستخدامه مع الامتداد.
class StringTools {
fun String.greet() = "Hello, $this!"
fun process(name: String) = with(this) {
name.greet()
}
}
fun main() {
println(StringTools().process("Ada"))
}خصائص الامتداد على Companion
يمكن أن تكون امتدادات companion خصائص أيضًا، ما يتيح إضافة ثوابت مُسمّاة من خارج الفئة.
class HttpStatus {
companion object
}
val HttpStatus.Companion.OK_CODE: Int get() = 200
val HttpStatus.Companion.NOT_FOUND: Int get() = 404
fun main() {
println(HttpStatus.OK_CODE)
println(HttpStatus.NOT_FOUND)
}أفضل الممارسات
استخدم private للمساعدات المحلية على مستوى الملف، وinternal لواجهات برمجة التطبيقات الخاصة بالوحدة، وامتدادات الأعضاء للتغليف، وامتدادات companion لإضافة مساعدات شبيهة بدوال إنشاء الكائنات من خارج الفئة.
class StringUtils {
companion object
}
fun StringUtils.Companion.isAlpha(s: String) = s.all { it.isLetter() }
fun main() {
println(StringUtils.isAlpha("hello"))
println(StringUtils.isAlpha("hi5"))
}تحقق سريع
ما المتطلب في الفئة حتى تتمكن من إضافة امتداد companion إليها من الخارج؟
مراجعة
حدّد نطاق الامتدادات باستخدام private أو internal أو باعتبارها امتدادات أعضاء داخل فئة. أضف امتدادات companion (دوالًا أو خصائص) من الخارج عبر إسنادها إلى كائن companion المعلن للفئة. يقلل ذلك من تلوث مساحة الأسماء مع الحفاظ على نمطية الشيفرة.
تعلم Kotlin مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 51
- الدروس
- 203
الأسئلة الشائعة
هل درس «الامتدادات ذات النطاق وامتدادات companion» مجاني؟
نعم — نص درس «الامتدادات ذات النطاق وامتدادات companion» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
ماذا ستتعلم في «الامتدادات ذات النطاق وامتدادات companion»؟
قيّد مستوى ظهور الامتدادات وأضف امتدادات إلى companion objects. تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟
لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «الامتدادات ذات النطاق وامتدادات companion»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟
نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- دوال الامتداد: الصياغة وقواعد الإرسال
- خصائص الامتداد والامتدادات المحسوبة
- الامتدادات ذات النطاق وامتدادات companion
- امتدادات عملية: مساعدات Context وView وString