الأصناف المتداخلة (Nested) والداخلية (Inner) في لغة Kotlin
الأصناف المتداخلة (Nested)
يُمكن للأصناف أن تتداخل فيما بينها، ويتَّضح ذلك عبر المثال الآتي:
class Outer {
private val bar: Int = 1
class Nested {
fun foo() = 2
}
}
val demo = Outer.Nested().foo() // == 2
إذ يتوضَّع الصنف باسم Nested
داخل الصنف Outer
، وعند تعريف المتحوِّل demo
فهو سيأخذ القيمة من الدالة foo
والموجودة في الصنف Nested
المُعرَّف بالصنف Outer
والتي هي القيمة 2
.
الأصناف الداخليَّة (Inner Classes)
يُمكن تحديد الصنف كصنفٍ داخليٍّ بالكلمة المفتاحيّة inner
وذلك بهدف إتاحة الوصول لكافّة عناصر الصنف الخارجيِّ الذي يحتويه (حتى وإن كانت مُعرَّفة من نوعٍ خاصِّ [private])؛ إذ يحتوي الصنف الداخليّ على مرجعيَّةٍ (reference) تعود للصنف الخارجيّ، وسيصبح المثال السابق بالشكل الآتي: (بإضافة الكلمة المفتاحيّة inner
أُتيحَ في الصنف الداخليِّ الوصولُ للمتحِّول bar
التابع للصنف الخارجيّ)
class Outer {
private val bar: Int = 1
inner class Inner {
fun foo() = bar
}
}
val demo = Outer().Inner().foo() // == 1
ولإزالة الغموض بما يتعلق باستخدام الكلمة المفتاحيّة this
في الصنف الداخليّ راجع التعبير this
.
الأصناف الداخليَّة المجهولة (Anonymous)
تٌنشَأ الأصناف الداخليّة المجهولة بواسطة تعبير الكائن (object expression)، وهذا مُوضَّح بالمثال الآتي:
window.addMouseListener(object: MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
فإذا كان الكائن مأخوذًا عن واجهة Java وظيفيَّة (functional Java interface) (وهي أيّ واجهة Java تحتوي على تابعٍ مُجرَّد (abstract method) واحدٍ على الأقل) فيُمكن إنشاؤه باستخدام تعبير lambda مسبوقًا بنوع الواجهة، كما يلي:
val listener = ActionListener { println("clicked") }