data class في Kotlin هو نوع خاص من الفئات مصمم حصرياً لتخزين البيانات. يُنشئ المترجم تلقائياً الطرق equals، hashCode، toString، copy و componentN بناءً على الخصائص المحددة في المُنشئ الأساسي. وفقاً لوثائق JetBrains (2026)، يسمح data class بتقليل حجم الكود المتكرر بنسبة 50–70% مقارنة بنظائره في Java وهو الأساس لكائنات القيمة في مشاريع Kotlin.
النقاط الرئيسية
data class هو تركيب نحوي في Kotlin يُنشئ تلقائياً طرقاً قياسية للفئات التي غرضها الرئيسي هو تخزين البيانات. عند الإعلان عن data class، يُنشئ المترجم تطبيقات لـ equals، hashCode، toString، copy و componentN بناءً على جميع الخصائص من المُنشئ الأساسي.
على عكس الفئات العادية في Java، حيث يتعين على المطور كتابة getters و setters و equals و hashCode و toString يدوياً باستخدام IDE أو مكتبات مثل Lombok، توفر Kotlin آلية مضمنة. هذا لا يقلل الكود فحسب بل يضمن أيضاً الاتساق — فالطرق التلقائية تتوافق دائماً مع هيكل الخصائص الحالي.
وفقاً لاستطلاع JetBrains Kotlin (2025)، يُستخدم data class في 78% من مشاريع Kotlin، مما يجعله أحد أكثر ميزات اللغة طلباً. إنه شائع بشكل خاص في البنى التي تحتوي على DTO ونماذج استجابة API وكائنات الحالة في MVVM.
يُعلن data class باستخدام الكلمة الأساسية data قبل class. تُحدد جميع الخصائص المشاركة في الطرق التلقائية في المُنشئ الأساسي.
data class User(
val id: Int,
val name: String,
val email: String
)
سطر واحد من الكود يحل محل عشرات الأسطر المتكررة في Java. يُنشئ المترجم equals، hashCode، toString، copy و component1–component3 لجميع الخصائص الثلاث.
تتضمن الطرق التلقائية فقط الخصائص من المُنشئ الأساسي. إذا تم الإعلان عن خاصية في جسم الفئة، فإنها لا تشارك في equals، hashCode، toString و copy.
data class Product(
val id: Int,
val title: String
) {
var cachedPrice: Double = 0.0
// cachedPrice is NOT included in equals/hashCode/copy
}
يجب أن يحتوي المُنشئ الأساسي لـ data class على معامل واحد على الأقل. يجب أن تكون جميع المعاملات محددة كـ val أو var. لا يمكن استخدام معدِّلات open أو abstract أو sealed أو inner مع data class.
يتم إنشاء equals و hashCode بناءً على قيم جميع الخصائص من المُنشئ الأساسي. يعتبر مثيلان من data class متساويين إذا كانت جميع خصائصهما المتناظرة متساوية.
في Java، مقارنة الكائنات افتراضياً هي مقارنة مراجع (==). المقارنة بالقيمة تتطلب تجاوز equals. يقوم Kotlin data class بذلك تلقائياً، مما يسمح باستخدام == للمقارنة الهيكلية.
data class Address(
val city: String,
val street: String
)
val a1 = Address("Moscow", "Tverskaya")
val a2 = Address("Moscow", "Tverskaya")
println(a1 == a2) // true
تعيد طريقة toString تمثيلاً مقروءاً للكائن بأسماء وقيم جميع الخصائص. هذا يبسط بشكل كبير التسجيل وتصحيح الأخطاء مقارنة بـ Java، حيث يُظهر الإخراج الافتراضي رمز التجزئة بتنسيق سداسي عشري.
وفقاً لوثائق Kotlin (2026)، يكون تنسيق toString لـ data class: “User(id=1, name=John, email=john@example.com)”. عند إزالة خصائص من المُنشئ الأساسي، يتم تحديث toString تلقائياً — يتم استبعاد خطر عدم التزامن.
copy هي إحدى الميزات الرئيسية لـ data class. تنشئ نسخة سطحية من الكائن مع إمكانية تغيير قيم الخصائص المحددة.
data class Order(
val id: Long,
val status: String,
val amount: Double
)
val order = Order(1L, "Pending", 299.99)
val updatedOrder = order.copy(status = "Confirmed")
// updatedOrder.id = 1L, amount = 299.99, status = "Confirmed"
copy لا غنى عنها في الأسلوب الوظيفي والبنى ذات الثبات. بدلاً من تغيير كائن موجود، يتم إنشاء نسخة جديدة مع حقول معدَّلة، مما يجعل الكود أكثر قابلية للتنبؤ وأماناً في السيناريوهات متعددة الخيوط.
يُنشئ data class تلقائياً الدوال component1 و component2 وهكذا لكل خاصية بترتيب إعلانها. هذا يسمح بتفكيك الكائن إلى متغيرات.
val user = User(1, "Alice", "alice@example.com")
val (id, name, email) = user
println("$id: $name ($email)") // "1: Alice (alice@example.com)"
يعمل التفكيك أيضاً في lambda وحلقات for-each، مما يجعل data class ملائماً للعمل مع المجموعات.
أول قيد — data class لا يدعم الوراثة من data class آخر. يمكن الوراثة فقط من الفئات العادية أو الواجهات.
ثانياً — تتضمن الطرق التلقائية فقط خصائص المُنشئ الأساسي. يتم تجاهل الخصائص في جسم الفئة، مما قد يؤدي إلى equals غير صحيح إذا نسيت ذلك.
ثالثاً — لا يمكن أن يكون data class من نوع open أو abstract أو sealed أو inner. إنه دائماً final.
رابعاً — بالنسبة للمجموعات داخل data class، تقوم copy بنسخ سطحي. سيؤثر تغيير العناصر داخل المجموعة المنسوخة على الأصل.
وفقاً ممارسات Kotlin (2026)، فإن data class هو الأمثل لـ DTO ونماذج API وكائنات القيمة وكائنات الحالة. بالنسبة للمكونات ذات منطق الأعمال، يُوصى باستخدام الفئات العادية.
الأسئلة الشائعة
لا، لا يمكن لـ data class أن يرث data class آخر. ومع ذلك، يمكنه وراثة فئة عادية أو تنفيذ واجهات.
خاصية واحدة على الأقل. الحد الأقصى غير محدود، ولكن يتم إنشاء componentN للتفكيك.
لا، تأخذ الطرق التلقائية في الاعتبار فقط الخصائص من المُنشئ الأساسي. الخصائص من جسم الفئة لا تشارك في equals و hashCode و toString و copy.
نعم، يمكنك تجاوز equals أو hashCode أو toString في جسم data class. في هذه الحالة، لا يُنشئ المترجم تطبيقه الخاص.
يُنشئ data class تلقائياً equals و hashCode و toString و copy و componentN. الفئة العادية لا توفر هذه الطرق دون تنفيذ يدوي.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا