الكلمات المفتاحية Virtual و Override
جزء من قسم البرمجة كائنية التوجه في رحلة C# على Coddy. الدرس 21 من 70.
عندما ترث فئة مشتقة دالة، قد ترغب أحيانًا في تغيير طريقة عمل تلك الدالة بالكامل. تعمل الكلمتان المفتاحيتان virtual وoverride معًا لإتاحة ذلك بطريقة مضبوطة.
علِّم أسلوبًا بأنه virtual في الفئة الأساسية للإشارة إلى أن الفئات المشتقة يُسمح لها باستبدال تنفيذه:
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("Some sound");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Woof!");
}
}تخبر الكلمة المفتاحية override في الفئة المشتقة المترجم بأنك تستبدل عمدًا الطريقة الأساسية. من دون virtual في الطريقة الأساسية، لا يمكنك استخدام override.
تظهر القوة الحقيقية عندما تستخدم مرجعًا إلى فئة أساسية للاحتفاظ بكائن مشتق:
Animal myPet = new Dog();
myPet.Speak(); // الناتج: Woof!على الرغم من أن myPet مُعرَّف على أنه Animal، يستدعي C# إصدار Dog من Speak(). يُسمّى هذا تعدد الأشكال وقت التشغيل - إذ تعتمد الطريقة الفعلية التي يتم استدعاؤها على النوع الحقيقي للكائن، لا على النوع المُعلن للمتغير.
لا يزال بإمكانك الوصول إلى التنفيذ الأساسي باستخدام base.Speak() داخل التجاوز إذا أردت توسيع السلوك بدلًا من استبداله بالكامل.
التحدي
سهللنبنِ نظام إشعارات يوضّح كيف يمكن للفئات المشتقة تجاوز سلوك الفئة الأساسية بالكامل باستخدام الكلمتين الأساسيتين virtual وoverride، مع إظهار قوة تعدد الأشكال وقت التشغيل.
ستنشئ ثلاثة ملفات لتنظيم التعليمات البرمجية:
Notification.cs: عرّف فئةNotificationفي مساحة الأسماءAlerts. تمثّل هذه الفئة الأساسية إشعارًا عامًا، وتتضمن خاصيةMessage(من النوع string) ومُنشئًا يعيّن قيمتها. أضف طريقةvirtualتُسمّىSend()وتُعيد"Sending notification: {Message}".EmailNotification.cs: عرّف فئةEmailNotificationفي مساحة الأسماءAlerts، بحيث ترث منNotification. أضف خاصيةRecipient(من النوع string) ومُنشئًا يقبل الرسالة والمستلِم معًا (استخدمbaseلتمرير الرسالة). أعد تعريف الطريقةSend()لتُعيد"Emailing {Recipient}: {Message}".SmsNotification.cs: عرّف فئةSmsNotificationفي مساحة الأسماءAlerts، بحيث ترث أيضًا منNotification. أضف خاصيةPhoneNumber(من النوع string) ومُنشئًا يقبل الرسالة ورقم الهاتف معًا. أعد تعريفSend()لتُعيد"SMS to {PhoneNumber}: {Message}".Program.cs: أنشئ في ملفك الرئيسي كائنات من أنواع الإشعارات الثلاثة باستخدام قيم الإدخال. ثم اعرض تعدد الأشكال وقت التشغيل من خلال تخزين الكائنات الثلاثة في متغيرات من النوعNotificationواستدعاءSend()على كل منها.
ستتلقى أربعة مدخلات:
- نص الإشعار
- عنوان البريد الإلكتروني للمستلِم
- رقم الهاتف للرسائل النصية القصيرة
اطبع نتيجة استدعاء Send() لكل إشعار، بعد تخزينه كمرجع إلى الفئة الأساسية:
{base notification Send() result}
{email notification Send() result}
{sms notification Send() result}على سبيل المثال، إذا كانت المدخلات هي Meeting at 3pm وalice@email.com و555-1234، فينبغي أن يكون الناتج:
Sending notification: Meeting at 3pm
Emailing alice@email.com: Meeting at 3pm
SMS to 555-1234: Meeting at 3pmلاحظ أنه على الرغم من تخزين الكائنات الثلاثة جميعها في متغيرات من النوع Notification، فإن كلًا منها يستدعي نسخته الخاصة المعاد تعريفها من Send(). هذا هو تعدد الأشكال وقت التشغيل عمليًا!
جرّب بنفسك
using System;
using Alerts;
class Program
{
public static void Main(string[] args)
{
// اقرأ المدخلات
string message = Console.ReadLine();
string email = Console.ReadLine();
string phone = Console.ReadLine();
// TODO: أنشئ كائنات من أنواع الإشعارات الثلاثة جميعها
// خزّنها في متغيرات من النوع Notification لتوضيح تعدد الأشكال
// TODO: أنشئ كائنًا من الفئة الأساسية Notification
Notification baseNotification;
// TODO: أنشئ كائنًا من EmailNotification (مخزّنًا في متغير من النوع Notification)
Notification emailNotification;
// TODO: أنشئ كائنًا من SmsNotification (مخزّنًا في متغير من النوع Notification)
Notification smsNotification;
// TODO: استدعِ Send() على كل منها واطبع النتائج
// سيُستدعى التنفيذ المُعاد تعريفه لكل طريقة بفضل تعدد الأشكال في وقت التشغيل
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injectionتدرّب بنفسك: مترجم C# عبر الإنترنت