الدرس 9 من 10
الوراثة والواجهات
- 16 دقيقة
- 5 معايير للتصحيح
- 3 تلميحات
- إلى المطلوب
هدف الدرس
abstract و override و interface
الشرح
الوراثة تبني صنفًا على آخر: class Goblin : Enemy يرث كل ما في Enemy من خصائص ودوال، ويمرّر مُنشئه البيانات إلى مُنشئ الأب بـ : base("عفريت", 30). وabstract class Enemy فكرة عامّة لا يُنشأ منها كائن مباشرة، فـ new Enemy(...) خطأ ترجمة: لا «عدوّ» مجرّد في اللعبة، بل عفريت أو فارس.
والدالة abstract بلا جسم، وكل صنف ابن ملزم بأن يكتبها بـ override. أما virtual فلها جسم افتراضي يجوز للابن أن يستبدله بـ override، ويستدعي نسخة الأب بـ base.TakeDamage(...). وهنا تعدّد الأشكال: في List<Enemy> عفاريت وفرسان معًا، وe.Attack() تستدعي نسخة كلٍّ منهم وقت التشغيل. والفخّ: دالة بالاسم نفسه بلا override تخفي دالة الأب ولا تستبدلها، فالمرجع من نوع Enemy يصل إلى نسخة الأب، والمترجم يكتفي بتحذير.
والواجهة عقد بلا تنفيذ: interface IDamageable { void TakeDamage(int amount); }. كل صنف يعلن : IDamageable ملزم بتنفيذ دوالها public، ولو لم يجمعه بغيره أب مشترك. وبها تضرب رصاصةٌ في Unity كل ما تصيبه، عدوًّا كان أو برميلًا، دون أن تعرف نوعه. والصنف يرث من أب واحد، لكنه ينفّذ ما شاء من الواجهات.
المطلوب
اجعل Enemy صنفًا abstract، وAttack() فيه دالة abstract، وTakeDamage دالة virtual. ثم اكتب Attack() بـ override في Goblin تُرجع 5، وفي Knight تُرجع 12، واجعل الفارس المدرّع يتلقّى نصف الضرر فقط بـ override لـ TakeDamage. واجعل Barrel ينفّذ IDamageable: أي ضربة تكسره فتصير Broken صحيحة. وأكمل TotalAttack(enemies) لتجمع هجمات الأحياء منهم وحدهم.
معايير التصحيح
5 معايير- Enemy و Attack فيه abstract
- كل عدوّ يهاجم بقوّته عبر مرجع Enemy: العفريت 5 والفارس 12
- الفارس يتلقّى نصف الضرر عبر مرجع Enemy، والعفريت كاملًا
- Barrel ينفّذ IDamageable وتكسره أي ضربة
- TotalAttack تجمع هجمات الأحياء وحدهم