الأصناف المتداخلة (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") }