Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

إعادة تعريف hashCode و ==

جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 71 من 110.

بشكل افتراضي، يكون أي كائنين في Dart متساويين فقط إذا كانا يمثلان نفس النسخة تماماً في الذاكرة. وهذا يعني أن كائنين بقيم متطابقة لا يزالان يُعتبران مختلفين:

class Point {
  int x, y;
  Point(this.x, this.y);
}

void main() {
  var p1 = Point(3, 4);
  var p2 = Point(3, 4);
  print(p1 == p2);  // خطأ - مثيلات مختلفة!
}

لمقارنة الكائنات حسب قيمها، تحتاج إلى تجاوز كل من معامل == و hashCode. يجب دائمًا تجاوز هذين الاثنين معًا - إذا كان كائنان متساويين، فيجب أن يكون لهما نفس رمز التجزئة (hash code):

class Point {
  final int x, y;
  Point(this.x, this.y);
  
  @override
  bool operator ==(Object other) {
    if (other is! Point) return false;
    return x == other.x && y == other.y;
  }
  
  @override
  int get hashCode => Object.hash(x, y);
}

void main() {
  var p1 = Point(3, 4);
  var p2 = Point(3, 4);
  print(p1 == p2);  // true - نفس القيم!
}

يُعد hashCode أمراً بالغ الأهمية لمجموعات مثل مفاتيح Set و Map. تقوم أداة Object.hash() المساعدة في Dart بدمج قيم متعددة في رمز تجزئة واحد. وبدون hashCode صحيح، لن تعمل كائناتك بشكل صحيح في المجموعات القائمة على التجزئة حتى لو تم تجاوز ==.

challenge icon

التحدي

سهل

لنقم ببناء نظام إحداثيات حيث يمكن مقارنة النقاط بقيمها بدلاً من عناوين ذاكرتها! ستقوم بإنشاء فئة Coordinate تنفذ المساواة القائمة على القيمة بشكل صحيح، مما يجعلها تعمل بشكل صحيح مع فحوصات المساواة والمجموعات القائمة على التجزئة (hash-based collections) مثل Set.

ستقوم بتنظيم الكود الخاص بك في ملفين:

  • coordinate.dart: أنشئ فئة Coordinate تمثل نقطة في فضاء ثنائي الأبعاد مع حقول final int x و final int y. قم بعمل override لكل من عامل التشغيل == و hashCode بحيث يتم اعتبار إحداثيين لهما نفس قيم x و y متساويين. استخدم Object.hash() لإنشاء رمز التجزئة (hash code) من كلا الحقلين.
  • main.dart: استورد ملف الإحداثيات الخاص بك ووضح كيف تغير المساواة القائمة على القيمة سلوك مقارنة الكائنات:
    • أنشئ كائنين منفصلين من Coordinate، كلاهما بقيمة x: 5 و y: 10
    • اطبع ما إذا كانا متساويين باستخدام ==
    • اطبع ما إذا كانا متطابقين (نفس المثيل) باستخدام identical()
    • أنشئ Set<Coordinate> وأضف كلا الإحداثيين إليها
    • اطبع طول المجموعة (يجب أن يكون 1 لأنهما متساويان!)
    • أنشئ إحداثياً ثالثاً بقيمة x: 3 و y: 7، وأضفه إلى المجموعة
    • اطبع الطول النهائي للمجموعة

يوضح هذا التحدي سبب وجوب عمل override لكل من hashCode و == معاً دائماً. تستخدم الـ Set رموز التجزئة لتنظيم العناصر، لذا بدون hashCode مناسب، حتى الكائنات المتساوية قد يتم تخزينها كنسخ مكررة!

المخرجات المتوقعة:

true
false
1
2

جرّب بنفسك

import 'coordinate.dart';

void main() {
  // TODO: قم بإنشاء كائنين منفصلين من النوع Coordinate، كلاهما بقيم x: 5 و y: 10

  // TODO: اطبع ما إذا كانا متساويين باستخدام ==

  // TODO: اطبع ما إذا كانا متطابقين (نفس النسخة) باستخدام identical()

  // TODO: قم بإنشاء Set<Coordinate> وأضف كلا الإحداثيين إليها

  // TODO: اطبع طول المجموعة (يجب أن يكون 1 لأنهما متساويان!)

  // TODO: قم بإنشاء إحداثي ثالث بقيم x: 3 و y: 7، وأضفه إلى المجموعة

  // TODO: اطبع الطول النهائي للمجموعة
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming