الفرق بين المراجعتين لصفحة: «Kotlin/data classes»
طلا ملخص تعديل |
ط استبدال النص - 'Kotlin Properties' ب'Kotlin Property' |
||
(مراجعتان متوسطتان بواسطة مستخدمين اثنين آخرين غير معروضتين) | |||
سطر 11: | سطر 11: | ||
* الدالة <code>copy()</code> | * الدالة <code>copy()</code> | ||
ويجب أن تُحقِّق أصناف البيانات الشروط الآتية لضمان الترابط والسلوك الفعّال في الشيفرة المُولَّدة: | ويجب أن تُحقِّق أصناف البيانات الشروط الآتية لضمان الترابط والسلوك الفعّال في الشيفرة المُولَّدة: | ||
* أن يحتوي الباني الأساسيّ (primary constructor) على | * أن يحتوي الباني الأساسيّ (primary constructor) على معامل (parameter) واحدٍ على الأقل | ||
* أن تكون | * أن تكون متغيِّراته إمّا من النوع <code>var</code> أو النوع <code>val</code> | ||
* ألّا يكون الصنف من النوع <code>abstract</code> أو <code>open</code> أو <code>sealed</code> أو <code>inner</code> | * ألّا يكون الصنف من النوع <code>abstract</code> أو <code>open</code> أو <code>sealed</code> أو <code>inner</code> | ||
* يمكن للصنف إعادة تعريف استخدام (implement) الواجهات (interfaces) فقط (هذا قبل الإصدار 1.1) | * يمكن للصنف إعادة تعريف استخدام (implement) الواجهات (interfaces) فقط (هذا قبل الإصدار 1.1) | ||
سطر 22: | سطر 22: | ||
ويُسمَح بدءًا من الإصدار 1.1 أن تكون أصناف البيانات إضافةً (extend) للأصناف الأخرى. (راجع [[Kotlin/sealed classes|الأصناف المغلقة [sealed classes]]] للحصول على الأمثلة) | ويُسمَح بدءًا من الإصدار 1.1 أن تكون أصناف البيانات إضافةً (extend) للأصناف الأخرى. (راجع [[Kotlin/sealed classes|الأصناف المغلقة [sealed classes]]] للحصول على الأمثلة) | ||
وإذا تطلَّب الصنف المُولَّد في JVM أن يحتوي على بانٍ بدون | وإذا تطلَّب الصنف المُولَّد في JVM أن يحتوي على بانٍ بدون معاملات (parameterless) فيجب حينئذٍ تحديد القيم الافتراضيّة لكافّة الخاصّيّات كما في الشيفرة: (راجع [[Kotlin/classes|البواني [constructors]]])<syntaxhighlight lang="kotlin"> | ||
data class User(val name: String = "", val age: Int = 0) | data class User(val name: String = "", val age: Int = 0) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
سطر 62: | سطر 62: | ||
[[تصنيف:Kotlin]] | [[تصنيف:Kotlin]] | ||
[[تصنيف:Kotlin Classes]] | [[تصنيف:Kotlin Classes]] | ||
[[تصنيف:Kotlin | [[تصنيف:Kotlin Function]] | ||
[[تصنيف:Kotlin | [[تصنيف:Kotlin Property]] | ||
[[تصنيف:Kotlin Inheritance]] | [[تصنيف:Kotlin Inheritance]] |
المراجعة الحالية بتاريخ 11:37، 30 أغسطس 2018
تُنشَأ بعض الأصناف بهدف تخزين البيانات فيها بشكلٍ أساسيّ، وبالتالي فإنّ كلّ ما تقوم به هذه الأصناف من وظائف يرتبط بالبيانات، وهذا ما يُسمى بأصناف البيانات في لغة Kotlin وتُعرَّف بالمُحدِّد data
كما يلي:
data class User(val name: String, val age: Int)
قواعد عامّة
يقوم المُترجِم في الأصناف من هذه النوع باشتقاق العناصر (deriving members) الآتية من كلِّ الخاصّيّات المُعرَّفة في الباني الأساسيّ (primary constructor):
- كلًا من
equals()
وhashCode()
- الدالة
toString()
بشكلها"User(name=John, age=42)"
- الدوال بالصيغة
componentN() functions
بما يتناسب مع الخاصّيّات وترتيبها أثناء التصريح - الدالة
copy()
ويجب أن تُحقِّق أصناف البيانات الشروط الآتية لضمان الترابط والسلوك الفعّال في الشيفرة المُولَّدة:
- أن يحتوي الباني الأساسيّ (primary constructor) على معامل (parameter) واحدٍ على الأقل
- أن تكون متغيِّراته إمّا من النوع
var
أو النوعval
- ألّا يكون الصنف من النوع
abstract
أوopen
أوsealed
أوinner
- يمكن للصنف إعادة تعريف استخدام (implement) الواجهات (interfaces) فقط (هذا قبل الإصدار 1.1)
وبما يخصُّ وراثة العناصر (members inheritance) فيجب التقيُّد بالقواعد الآتية:
- إذا وُجِد تعريف استخدام (implementation) الدوال
equals()
أوhashCode()
أوtoString()
في صنف البيانات أو إعادة تعريف استخدامٍ من النوعfinal
في الصنف الأعلى (superclass) فإنّ هذه الدوال لا تُولَّد (generated) بل تُستخدم تعريفاتها الموجودة. - إذا احتوى النوع الأعلى (supertype) على دوال
componentN()
المفتوحة (من النوعopen
) والتي تعيد أنواعًا متوافقة، حينها تُولَّد الدوال المُوافقة في صنف البيانات ويُعاد تعريف (override) تلك الدوال في النوع الأعلى، وإذا لم يكن من الممكن إعادة تعريفها بسبب كونهاfinal
أو عدم التوافق في ترويستها (signature) فسينتُج خطأ عن ذلك. - يُحدُّ في Kotlin 1.2 من اشتقاق صنف البيانات من نوعٍ يحتوي على دالة copy(...) وبتأشيرةٍ متوافقةٍ (matching signature) وسيُمنع ذلك بدءًا من الإصدار Kotlin 1.3.
- لا يُسمح بوجود تعريف الاستخدام (implementation) الصريح لأيّ من الدالتين
componentN()
وcopy()
.
ويُسمَح بدءًا من الإصدار 1.1 أن تكون أصناف البيانات إضافةً (extend) للأصناف الأخرى. (راجع الأصناف المغلقة [sealed classes] للحصول على الأمثلة)
وإذا تطلَّب الصنف المُولَّد في JVM أن يحتوي على بانٍ بدون معاملات (parameterless) فيجب حينئذٍ تحديد القيم الافتراضيّة لكافّة الخاصّيّات كما في الشيفرة: (راجع البواني [constructors])
data class User(val name: String = "", val age: Int = 0)
الخاصيات (Properties) المُعرَّفة في بنية الصنف (Class Body)
يَستخدِم المُترجِم الخاصّيّات المُعرَّفة داخل الباني الأساسيّ (primary constructor) للدوال المولَّدة تلقائيًا فقط، وبالتالي فإنه لاستبعاد أيّ خاصّيّة من تعاريف الاستخدام (implementations) المُولَّدة، يجب تعريفها في بُنية الصنف، مثل:
data class Person(val name: String) {
var age: Int = 0
}
ففي الشيفرة السابقة يُسمَح باستخدام الخاصية name
فقط في أيّ من الدوال equals()
و hashCode()
و toString()
و copy()
وسيكون هناك دالة واحد للعناصر (component function) باسم component1()
، وعلى الرغم من أنّه يمكن أن يكون لكائنين من النوع Person
أعمارٌ مختلفةٌ فإنها ستُعامَل وكأنها متساوية، جرِّب الشيفرة الآتية:
val person1 = Person("John")
val person2 = Person("John")
person1.age = 10
person2.age = 20
إذ يُعدُّ الشرط: person1 == person2
بقيمة true
.
دالة النسخ copy()
قد تحتاج في حالاتٍ كثيرة إلى استنساخ كائنٍ ما (object) والتعديل في "بعض" خاصّيّاته (properties) مع المحافظة على الأخرى كما هي بدون تعديل، وهذا ما تقوم به الدالة copy()
، ففي الصنف السابق User
سيكون تعريف استخدام (implementation) الدالة كما يلي:
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
وهذا سيُتيح الاستخدام الآتي في الشيفرة:
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)
أصناف البيانات وتفكيك التصريحات (Destructuring Declarations)
تُولَّد دوال العناصر (component functions) بهدف استخدامها في تفكيك التصريحات في أصناف البيانات، كما في الشيفرة الآتية:
val jane = User("Jane", 35)
val (name, age) = jane
println("$name, $age years of age") // ستظهر العبارة "Jane, 35 years of age"
أصناف البيانات القياسيّة (Standard Data Classes)
توفّر المكتبة القياسيّة الصنفين Pair
و Triple
لأنّ استخدام أصناف البيانات المُسماة يكون -في معظم الأحيان- خيارًا أفضل، لأنّها تجعل الشيفرة أسهل قراءةً عبر تزويدها بأسماءٍ معبِّرةٍ للخاصّيّات.