מילות המפתח 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(מחרוזת) ובנאי שמגדיר אותו. כללו מתודה בשם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() בכל אחד מהם והדפס את התוצאות
// המתודות שנדרסו ייקראו בזכות פולימורפיזם בזמן ריצה
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמרחבי שמות והנחיותמבוא למחלקות ולאובייקטיםמילת המפתח 'this'מתודות ופרמטריםשדות לעומת מאפייניםבנאיםאתחול אובייקטיםסיכום – מחשבון פשוט4ירושה
תחביר ירושה בסיסית (:)מילת המפתח 'base'מילות המפתח Virtual ו-Overrideמחלקות Sealedמחלקת הבסיס 'object'סיכום – היררכיית עובדים7תכונות מתקדמות
העמסת אופרטוריםאינדקסרים (this[])דריסת ToString()מתודות הרחבהסיכום – רשימה מותאמת אישית2מאפיינים וחברים סטטיים
מאפיינים במימוש אוטומטימאפיינים לקריאה בלבד ולכתיבה בלבדשדות ומתודות סטטייםמחלקות סטטיותחברים עם גוף ביטוי5פולימורפיזם וממשקים
פולימורפיזם בזמן קומפילציה לעומת בזמן ריצהממשק לעומת מחלקה מופשטתממשקים מרוביםממשקים מפורשיםהמרה כלפי מעלה והמרה כלפי מטהחזרה: מחשבון צורות8מושגים מתקדמים בתכנות מונחה עצמים
קומפוזיציה במקום ירושהGenerics (מחלקות ומתודות)נציגים ואירועיםמאפיינים ורפלקציהIDisposable והצהרת usingיסודות הזרקת תלויותתרגלו בעצמכם: קומפיילר C# אונליין