الفرق بين المراجعتين لصفحة: «Kotlin/classes»
إضافة فقرة البواني |
إنهاء قسم الأصناف |
||
سطر 73: | سطر 73: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== <span> </span>إنشاء كائنات من الصنف () == | === <span> </span>إنشاء كائنات (Instances) من الصنف === | ||
لإنشاء كائنٍ من أحد الأصناف يُستدَعى الباني (constructor) فيه كما لو أنّه دالةٌ عاديّة، مثل:<syntaxhighlight lang="kotlin"> | |||
val invoice = Invoice() | |||
=== عناصر الصنف () === | val customer = Customer("Joe Smith") | ||
</syntaxhighlight>إذ لا تعتمد لغة Kotlin على وجود الكلمة المفتاحيّة <code>new</code> كما هو الحال في لغة Java. | |||
أمّا لإنشاء الكائنات من الأصناف المتداخلة (nested) أو الأصناف الداخليّة (inner) أو الداخليّة المجهولة (anonymous inner) راجع [[Kotlin/nested classes|الأصناف المتداخلة]]. | |||
=== عناصر الصنف (Class Members) === | |||
قد يحتوي الصنف على: | |||
* [[Kotlin/classes|البواني وأجزاء التهيئة (constructors and initializer blocks)]] | |||
* [[Kotlin/functions|الدوال (functions)]] | |||
* [[Kotlin/properties|الخاصّيّات (properties)]] | |||
* [[Kotlin/nested classes|الأصناف المتداخلة والداخلية (nested and inner classes)]] | |||
* [[Kotlin/object declarations|التصريح عن الكائنات (object declarations)]] | |||
== الوراثة == | == الوراثة == |
مراجعة 14:22، 9 مارس 2018
الأصناف (Classes)
تُستخدم الكلمة المفتاحيّة class
للتصريح (declaration) عن الصنف بالصيغة الآتية: (اسم الصنف Invoice
)
class Invoice {
}
ويحتوي التصريح على اسم الصنف (class name) وترويسة الصنف (class header) (والتي تُحدِّد متحولات النوع والباني الأساسيّ و.. إلخ.) وبُنية الصنف (class body) محاطةً بالقوسين {}
، وإن كلًا من ترويسة الصنف وبُنيته اختياريتان؛ فإذا كان الصنف خاليًا لا حاجة للأقواس، مثل:
class Empty
الباني (Constructor)
يوجد لكلّ صنف في لغة Kotlin بانٍ رئيسيّ (primary) واحدٌ وبانٍ -أو أكثر- ثانويّ (secondary)، إذ يُعدُّ الباني الرئيسيّ جزءًا من ترويسة الصنف (header) حيث يُضاف بعد اسم الصنف مباشرةً (وقد تُضاف له المتحولات (parameters))، مثل:
class Person constructor(firstName: String) {
}
وإن لم يكن للباني الرئيسيّ حاشيةٌ (annotation) أو مُحدِّد وصول (visibility modifier) فتُحذَف حينئذِ الكلمة المفتاحيّة constructor
مثل:
class Person(firstName: String) {
}
وكما يُلاحظ أن الباني الرئيسيّ لا يحتوي على أيّة شيفرةٍ لأنّ شيفرة التهيئة الأولية (initialization code) تُكتب في أجزاء خاصّةٍ للتهيئة (initializer blocks) والتي تُسبَق بالكلمة المفتاحيّة init
، إذ تُنفَّذُ هذه الأجزاء -عند عملية الإنشاء من هذا الصنف- بنفس الترتيب الموجودة فيه ضمن الصنف متداخلةً مع عمليات تهيئة الخاصّيّات (property initializers)، مثل:
class InitOrderDemo(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
ويٌسمَح باستخدام متحوِّلات (parameters) الباني الأساسيّ في أجزاء التهيئة كما يُمكِن استخدامها أيضًا في تهيئة الخاصّيّات (properties) المُصرَّح عنها في بُنية الصنف (class body)، مثل:
class Customer(name: String) {
val customerKey = name.toUpperCase()
}
وتدعم Kotlin صيغةً مختصرةً للتصريح عن الخاصّيّات وتهيئتها الأولية في الباني الأساسيّ، وهي:
class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}
وكما هو الحال في الخاصّيّات بشكلٍ عامّ، قد تُعرَّف الخاصّيّات في الباني الأساسيّ كخاصيّات متغيّرة (mutable) var
أو خاصّيات للقراءة فقط (read-only) val
.
وفي حال وجود حاشيةٍ (annotation) أو مُحدِّد وصولٍ (visibility modifier) للباني فلا بُدَّ من وجود الكلمة المفتاحيّة constructor
إذ تُوضع الحاشية أو المُحدِّدات قبلها بالصيغة:
class Customer public @Inject constructor(name: String) { ... }
المزيد عن مُحدِّدات الوصول (visibility modifiers).
الباني الثانويّ (Secondary Constructors)
يُصرَّح عن الباني الثانويّ في الصنف (class) بالبدء به عبر الكلمة المفتاحيّة constructor
، مثل:
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
فإذا احتوى الصنف بانيًا رئيسيًا (primary constructor) فإن كلَّ بانٍ ثانويّ سيُفضي في النهاية إليه إما مباشرةً أو بطريقةٍ غير مباشرة عبر بانٍ ثانويّ آخر، وبكلا الحالتين يكون الوصول للباني الرئيسيّ من خلال الكلمة المفتاحيّة this
، مثل:
class Person(val name: String) {
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
ويُلاحظ بأن الشيفرة في أجزاء التهيئة (initializer blocks) تصبح جزءًا من الباني الأساسيّ حيث يكون الانتقال للباني الرئيسيّ بمثابة التعليمة الأولى في الباني الثانويّ، وبالتالي فإن كلّ الشيفرات الموجودة في أجزاء التهيئة ستُنفَّذ قبل الباني الثانويّ، حتى وإن لم يكن هناك بانٍ رئيسيّ للصنف فإن هذا الانتقال سيكون ضمنيًا (implicit) وستُنفَّذ أجزاء التهيئة أيضًا، مثل:
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor")
}
}
أما إذا لم يحتوِ الصنف (غير المُجرَّد non-abstract) على أي تصريحٍ لبانٍ (رئيسيّ أو ثانويّ) فسيُولَّد تلقائيًا بانٍ افتراضيّ بدون متحولات (arguments)، ويكون مُحدِّد الوصول له من النوع العامّ (public)، فإذا أردت ألا يكون عامًّا فعليك بإنشاء باني رئيسيٍّ فارغٍ وبالمُحدِّد المناسب، مثل:
class DontCreateMe private constructor () {
}
ويُلاحظ في بيئة JVM أنّه إن كان لكل متحوِّلات (parameters) الباني قيمٌ افتراضيّةٌ فإن المُترجم (compiler) سيُولِّد بانيًا إضافيًا بدون متحولات (parameterless)، والذي سيستخدم القيم الافتراضيّة، وهذا ما يجعل لغة Kotlin سهلة الاستخدام مع المكتبات (libraries) مثل Jackson أو JPA اللتان تنشِئان الكائنات باستخدام البواني بدون المتحولات. مثل:
class Customer(val customerName: String = "")
إنشاء كائنات (Instances) من الصنف
لإنشاء كائنٍ من أحد الأصناف يُستدَعى الباني (constructor) فيه كما لو أنّه دالةٌ عاديّة، مثل:
val invoice = Invoice()
val customer = Customer("Joe Smith")
إذ لا تعتمد لغة Kotlin على وجود الكلمة المفتاحيّة new
كما هو الحال في لغة Java.
أمّا لإنشاء الكائنات من الأصناف المتداخلة (nested) أو الأصناف الداخليّة (inner) أو الداخليّة المجهولة (anonymous inner) راجع الأصناف المتداخلة.
عناصر الصنف (Class Members)
قد يحتوي الصنف على:
- البواني وأجزاء التهيئة (constructors and initializer blocks)
- الدوال (functions)
- الخاصّيّات (properties)
- الأصناف المتداخلة والداخلية (nested and inner classes)
- التصريح عن الكائنات (object declarations)
الوراثة
إعادة تعريف التوابع ()
إعادة تعريف الخاصيات ()
ترتيب تهيئة الصنف المشتق
استدعاء إعادة التعريف من الصنف الأعلى
إعادة تعريف القواعد
الأصناف المجردة ()