تجاوز الدوال وتعليق @Override
تجاوز الدوال وتعليق @Override
يُتيح الوراثةُ للصنف الفرعي إعادةَ استخدام كود الصنف الأب. لكن ماذا لو احتاج الفرعي إلى تغيير آلية عمل دالة موروثة؟ هنا يأتي دور تجاوز الدوال (Method Overriding). تكتب تنفيذًا جديدًا للدالة الأبوية داخل الصنف الفرعي، فيستدعي Java نسخة الفرعي في كل مرة يكون فيها الكائن من نوع الفرعي.
ما هو تجاوز الدوال؟
عندما يُعرِّف الصنف الفرعي تنفيذه الخاص لدالة موجودة بالفعل في الصنف الأب، يُسمّى ذلك تجاوزًا. يجب أن تحمل الدالة في الفرعي الاسم ذاته، وقائمة المعاملات ذاتها، ونوع إرجاع متوافقًا مع تلك الموجودة في الأب.
عند استدعاء speak() على كائن Dog، يُشغِّل Java نسخة Dog لا نسخة Animal — حتى لو كان نوع المتغير Animal. (ستستكشف ذلك بعمق في درس تعدد الأشكال.)
تعليق @Override
يُتيح لك Java وضع تعليق @Override على الدالة المتجاوِزة. هذا اختياري في وقت التشغيل، لكنه موصى به بشدة.
القواعد الأربع للتجاوز
- الاسم ذاته — يجب أن يتطابق تمامًا.
- قائمة المعاملات ذاتها — العدد والأنواع والترتيب. المعاملات المختلفة تنشئ دالة زائدة تحميل جديدة، لا تجاوزًا.
- نوع إرجاع متوافق — إما النوع ذاته أو نوع فرعي منه (الإرجاع المتغاير؛ انظر أدناه).
- معدِّل الوصول لا يجوز أن يكون أكثر تقييدًا — إن أعلن الأب
public، لا يجوز للفرعي الإعلان عنprotectedأوprivate. يمكن الإبقاء عليهpublicأو توسيعه، لكن لا تضييقه أبدًا.
@Override على دالة تختلف فقط في المعاملات، سيكتشف المُترجم الخطأ.
أنواع الإرجاع المتغايرة
منذ Java 5، يجوز للدالة المتجاوِزة أن تُرجع نوعًا فرعيًا من نوع إرجاع الأب. يُسمّى هذا نوع الإرجاع المتغاير (Covariant Return Type). يُفيد ذلك حين يُرجع الأب نوعًا عامًا والفرعي يستطيع ضمان شيء أكثر تحديدًا.
يحصل مستدعو Circle.copy() على Circle مباشرةً دون أي تحويل نوع. يُحسِّن ذلك سلامة الأنواع دون كسر التوافق.
ما الذي لا يمكن تجاوزه
- الدوال
private— غير مرئية للأصناف الفرعية، لذا لا يمكن تجاوزها (بل إخفاؤها فقط). - الدوال
static— تُحلَّل في وقت التجميع لا في وقت التشغيل. يمكن للفرعي تعريف دالة ساكنة بالتوقيع ذاته، لكن ذلك يُسمّى إخفاء الدوال (Method Hiding)، لا تجاوزًا. - الدوال
final— تحظر الكلمة المفتاحيةfinalصراحةً أي تجاوز. ستتعلم عنfinalفي درس لاحق.
مثال كامل قابل للتشغيل
يُعرِّف كل صنف ما تعنيه المكافأة لنوعه الخاص. استدعاء الدالة ذاتها ينتج نتائج مختلفة تبعًا للكائن الفعلي — هذه هي قوة التجاوز جنبًا إلى جنب مع تعدد الأشكال.
الخلاصة
- يُتيح التجاوز للصنف الفرعي استبدال تنفيذ دالة أبوية.
- أضف
@Overrideدائمًا — يكتشف المُترجم الأخطاء الإملائية والتعارضات نيابةً عنك. - التزم بالقواعد الأربع: الاسم ذاته، المعاملات ذاتها، نوع إرجاع متوافق (متغاير)، ومعدِّل وصول مساوٍ أو أوسع.
- أنواع الإرجاع المتغايرة تُتيح إرجاع نوع أكثر تحديدًا دون كسر العقد.
- الدوال
privateوstaticوfinalلا يمكن تجاوزها.