الفرق بين المراجعتين ل"Kotlin/nested classes"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
ط
(تعديل مصطلح متحول)
 
سطر 9: سطر 9:
 
}
 
}
 
val demo = Outer.Nested().foo() // == 2
 
val demo = Outer.Nested().foo() // == 2
</syntaxhighlight>إذ يتوضَّع الصنف باسم <code>Nested</code> داخل الصنف <code>Outer</code> ، وعند تعريف المتحوِّل <code>demo</code> فهو سيأخذ القيمة من الدالة <code>foo</code> والموجودة في الصنف <code>Nested</code> المُعرَّف بالصنف <code>Outer</code> والتي هي القيمة <code>2</code>.
+
</syntaxhighlight>إذ يتوضَّع الصنف باسم <code>Nested</code> داخل الصنف <code>Outer</code> ، وعند تعريف المتغيِّر <code>demo</code> فهو سيأخذ القيمة من الدالة <code>foo</code> والموجودة في الصنف <code>Nested</code> المُعرَّف بالصنف <code>Outer</code> والتي هي القيمة <code>2</code>.
  
 
== الأصناف الداخليَّة (Inner Classes) ==
 
== الأصناف الداخليَّة (Inner Classes) ==
يُمكن تحديد الصنف كصنفٍ داخليٍّ بالكلمة المفتاحيّة <code>inner</code> وذلك بهدف إتاحة الوصول لكافّة عناصر الصنف الخارجيِّ الذي يحتويه (حتى وإن كانت مُعرَّفة من نوعٍ خاصِّ [private])؛ إذ يحتوي الصنف الداخليّ على مرجعيَّةٍ (reference) تعود للصنف الخارجيّ، وسيصبح المثال السابق بالشكل الآتي: (بإضافة الكلمة المفتاحيّة <code>inner</code> أُتيحَ في الصنف الداخليِّ الوصولُ للمتحِّول <code>bar</code> التابع للصنف الخارجيّ)<syntaxhighlight lang="kotlin">
+
يُمكن تحديد الصنف كصنفٍ داخليٍّ بالكلمة المفتاحيّة <code>inner</code> وذلك بهدف إتاحة الوصول لكافّة عناصر الصنف الخارجيِّ الذي يحتويه (حتى وإن كانت مُعرَّفة من نوعٍ خاصِّ [private])؛ إذ يحتوي الصنف الداخليّ على مرجعيَّةٍ (reference) تعود للصنف الخارجيّ، وسيصبح المثال السابق بالشكل الآتي: (بإضافة الكلمة المفتاحيّة <code>inner</code> أُتيحَ في الصنف الداخليِّ الوصولُ للمتغيِّر <code>bar</code> التابع للصنف الخارجيّ)<syntaxhighlight lang="kotlin">
 
class Outer {
 
class Outer {
 
   private val bar: Int = 1
 
   private val bar: Int = 1

المراجعة الحالية بتاريخ 16:06، 4 يوليو 2018

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

مصادر