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

إعادة تعريف الدوال (@Override)

جزء من قسم البرمجة كائنية التوجه في رحلة Java على Coddy. الدرس 22 من 87.

تجاوز method يسمح لفئة فرعية بتوفير تطبيقها الخاص لـ method تم تعريفه مسبقًا في فئتها parent. هكذا تُخصِّص الفئات الابنة behavior الموروث ليلائم احتياجاتها المحددة.

عندما تقوم overriding لـ method، فإن إصدار الفئة الفرعية يستبدل إصدار parent بالكامل بالنسبة إلى object من تلك الفئة الفرعية. يجب أن تحمل method الاسم نفسه والمعلمات نفسها مثل method الخاصة بـ parent، وأن يكون نوع الإرجاع نفسه (أو subtype منه) الخاص بـ parent:

public class Animal {
    public void makeSound() {
        System.out.println("Some generic sound");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof!");
    }
}

public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow!");
    }
}

تخبر التعليمة التوضيحية @Override الـcompiler بأنك تنوي تجاوز method في parent. ورغم أنها اختيارية، يُنصح بها بشدة لأن الـcompiler سيكتشف الأخطاء إذا أخطأتَ عن طريق الخطأ في تهجئة اسم method أو استخدمتَ معاملات غير صحيحة:

@Override
public void makeSound() { }  // صحيح - يتحقق المترجم من هذا

public void makesound() { }  // خطأ مطبعي! ينشئ دالة جديدة بدلاً من إعادة التعريف

عندما تستدعي method تمت إعادة تعريفها، تنفّذ Java الإصدار الذي ينتمي إلى النوع الفعلي للكائن:

Dog dog = new Dog();
dog.makeSound();  // المخرجات: Woof!

Cat cat = new Cat();
cat.makeSound();  // المخرجات: Meow!

تذكّر من الدرس السابق أنه يمكنك استخدام super.methodName() داخل method تمّت إعادة تعريفه إذا كنت لا تزال تريد تضمين behavior الخاص بـ parent إلى جانب كودك الجديد.

challenge icon

التحدي

سهل

لنَبْنِ نظام notification يوضّح كيف يمكن للفئات الفرعية تجاوز أساليب الفئة parent لتوفير سلوك متخصص خاص بها. سترى كيف تساعد التعليمة التوضيحية @Override في اكتشاف الأخطاء، وكيف يمكن لكل فئة فرعية تخصيص الأساليب الموروثة.

ستنشىء ثلاثة ملفات لتنظيم التعليمات البرمجية:

  • Notification.java: أنشئ فئة parent تمثّل إشعارًا generic. يجب أن تحتوي على:
    • حقل private لـ message من النوع (String)
    • مُنشئ constructor يقبل message
    • أسلوب getMessage() يعيد message
    • أسلوب send() يطبع: Sending notification: [message]
  • EmailNotification.java: أنشئ فئة فرعية تمتد من Notification وتخصّص كيفية إرسال notifications عبر email:
    • حقل private لـ recipient، أي عنوان email من النوع (String)
    • مُنشئ يأخذ كلًا من message وrecipient، باستخدام super(message) لجزء الفئة parent
    • تجاوز أسلوب send() باستخدام التعليمة التوضيحية @Override لطباعة: Emailing [recipient]: [message]
  • Main.java: وضّح كيف ينتج اسم الأسلوب نفسه سلوكًا مختلفًا اعتمادًا على نوع object. ستتلقى مُدخلين: message وعنوان email. أنشئ كلاً من Notification عادي وEmailNotification باستخدام message نفسه، ثم استدعِ send() على كل منهما لرؤية المخرجات المختلفة.

ستتلقى مُدخلين: message من النوع (String) وعنوان email الخاص بـ recipient من النوع (String).

يجب أن يُظهر ناتجك سطرين — الأول من أسلوب send() في الفئة parent، ثم من الإصدار الذي تم تجاوزه في EmailNotification. يوضّح هذا كيف يتيح تجاوز الأساليب للفئات الفرعية استبدال السلوك الموروث بتنفيذ خاص بها.

جرّب بنفسك

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // قراءة المدخلات
        String message = scanner.nextLine();
        String recipient = scanner.nextLine();
        
        // TODO: Create a Notification object with the message
        
        // TODO: Create an EmailNotification object with the message and recipient
        
        // TODO: Call send() on the Notification object
        
        // TODO: Call send() on the EmailNotification object
    }
}
quiz iconاختبر نفسك

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Java عبر الإنترنت