Menu
Coddy logo textTech

מילות המפתח 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() בתוך הדריסה שלך אם רוצים להרחיב את ההתנהגות במקום להחליף אותה לחלוטין.

challenge icon

אתגר

קל

בואו נבנה מערכת התראות שמדגימה איך מחלקות נגזרות יכולות לדרוס לחלוטין את ההתנהגות של מחלקת הבסיס באמצעות מילות המפתח virtual ו-override, וגם מציגה את העוצמה של פולימורפיזם בזמן ריצה.

תיצרו שלושה קבצים כדי לארגן את הקוד שלכם:

  • Notification.cs: הגדירו מחלקה בשם Notification במרחב השמות Alerts. מחלקת הבסיס הזו מייצגת התראה כללית עם מאפיין Message (מחרוזת) ובנאי שמגדיר אותו. כללו מתודה בשם Send() עם מילת המפתח virtual, שמחזירה את "Sending notification: {Message}".
  • EmailNotification.cs: הגדירו מחלקה בשם EmailNotification במרחב השמות Alerts, שיורשת מ-Notification. הוסיפו מאפיין Recipient (מחרוזת) ובנאי שמקבל גם הודעה וגם נמען (השתמשו ב-base כדי להעביר את ההודעה). דרסו את המתודה Send() כך שתחזיר את "Emailing {Recipient}: {Message}".
  • SmsNotification.cs: הגדירו מחלקה בשם SmsNotification במרחב השמות Alerts, שגם היא יורשת מ-Notification. הוסיפו מאפיין PhoneNumber (מחרוזת) ובנאי שמקבל גם הודעה וגם מספר טלפון. דרסו את Send() כך שתחזיר את "SMS to {PhoneNumber}: {Message}".
  • Program.cs: בקובץ הראשי, צרו מופעים של כל שלושת סוגי ההתראות באמצעות ערכי הקלט. לאחר מכן הדגימו פולימורפיזם בזמן ריצה על ידי אחסון שלושתם במשתנים מסוג Notification וקריאה ל-Send() על כל אחד מהם.

תקבלו ארבעה קלטים:

  • הודעת ההתראה
  • כתובת הנמען של האימייל
  • מספר טלפון עבור SMS

הדפיסו את התוצאה של קריאה ל-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() בכל אחד מהם והדפס את התוצאות
        // המתודות שנדרסו ייקראו בזכות פולימורפיזם בזמן ריצה
    }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר C# אונליין