Menu
Coddy logo textTech

המרה כלפי מעלה והמרה כלפי מטה

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C# של Coddy. שיעור 29 מתוך 70.

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

המרה למחלקת בסיס מתבצעת באופן משתמע והיא תמיד בטוחה, כי מובטח שלמחלקה יורשת יש את כל מה שיש למחלקת הבסיס:

Dog myDog = new Dog();
Animal animal = myDog;  // המרה לטיפוס־על - מתבצעת במובלע, תמיד עובדת

המרה כלפי מטה דורשת המרה מפורשת, ועלולה להיכשל בזמן ריצה אם האובייקט אינו באמת מהסוג שאליו ממירים אותו:

Animal animal = new Dog();
Dog dog = (Dog)animal;  // המרה מטה - פועלת כי זה באמת Dog

Animal cat = new Cat();
Dog wrong = (Dog)cat;   // זורק InvalidCastException!

כדי לבצע המרה כלפי מטה בבטחה, השתמשו במילת המפתח is כדי לבדוק קודם את הטיפוס, או השתמשו ב־as, שמחזירה null במקום לזרוק חריגה:

if (animal is Dog d)
{
    d.Bark();  // בטוח - d זמין רק אם הבדיקה מצליחה
}

Dog maybeDog = animal as Dog;
if (maybeDog != null)
{
    maybeDog.Bark();
}

גישת התאמת התבניות is עדיפה ב־C# מודרני, משום שהיא משלבת את בדיקת הטיפוס וההמרה לצעד אחד, וכך הקוד שלך בטוח ונקי יותר.

challenge icon

אתגר

קל

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

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

  • Vehicle.cs: הגדירו מחלקת בסיס Vehicle במרחב השמות Inspection. לכל כלי רכב יש מאפיין LicensePlate (מחרוזת) שמוגדר דרך בנאי. כללו מתודה בשם GetBasicInfo() שמחזירה "Vehicle: {LicensePlate}".
  • Car.cs: הגדירו מחלקה Car במרחב השמות Inspection שיורשת מ-Vehicle. למכוניות יש מאפיין נוסף, NumberOfDoors (מספר שלם). הבנאי מקבל גם את מספר לוחית הרישוי וגם את מספר הדלתות. הוסיפו מתודה בשם Honk() שמחזירה "{LicensePlate} honks: Beep beep!".
  • Motorcycle.cs: הגדירו מחלקה Motorcycle במרחב השמות Inspection שיורשת מ-Vehicle. לאופנועים יש מאפיין HasSidecar (בוליאני). הבנאי מקבל את מספר לוחית הרישוי ואת מצב הסירה הצדדית. הוסיפו מתודה בשם Rev() שמחזירה "{LicensePlate} revs: Vroom!".
  • Program.cs: בקובץ הראשי שלכם, תיצרו כלי רכב ותתרגלו גם המרה כלפי מעלה וגם המרה בטוחה כלפי מטה. צרו Car ו-Motorcycle באמצעות ערכי קלט, ואז אחסנו את שניהם במערך של הפניות מסוג Vehicle (המרה כלפי מעלה). עברו בלולאה על המערך והדפיסו את המידע הבסיסי של כל כלי רכב. לאחר מכן השתמשו במילת המפתח is עם התאמת תבניות כדי לבצע המרה בטוחה כלפי מטה: אם זה Car, קראו ל-Honk(); אם זה Motorcycle, קראו ל-Rev().

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

  • מספר לוחית הרישוי של המכונית
  • מספר הדלתות
  • מספר לוחית הרישוי של האופנוע
  • האם יש סירה צדדית (true או false)

הדפיסו את הפלט בפורמט הזה עבור כל כלי רכב במערך:

{GetBasicInfo() result}
{Honk() or Rev() result based on actual type}

לדוגמה, אם ערכי הקלט הם ABC-123, 4, XYZ-789 ו-false, הפלט אמור להיות:

Vehicle: ABC-123
ABC-123 honks: Beep beep!
Vehicle: XYZ-789
XYZ-789 revs: Vroom!

שימו לב שכל כלי הרכב מאוחסנים כהפניות מסוג Vehicle (המרה כלפי מעלה), אבל אפשר לזהות בבטחה את הסוגים האמיתיים שלהם ולגשת למתודות הספציפיות לסוג באמצעות תחביר התאמת התבניות של is לצורך המרה כלפי מטה!

נסו בעצמכם

using System;
using Inspection;

class Program
{
    public static void Main(string[] args)
    {
        // קראו את הקלטים
        string carPlate = Console.ReadLine();
        int numberOfDoors = Convert.ToInt32(Console.ReadLine());
        string motorcyclePlate = Console.ReadLine();
        bool hasSidecar = Convert.ToBoolean(Console.ReadLine());
        
        // TODO: צרו אובייקט Car באמצעות carPlate ו-numberOfDoors
        
        // TODO: צרו אובייקט Motorcycle באמצעות motorcyclePlate ו-hasSidecar
        
        // TODO: צרו מערך של הפניות מסוג Vehicle המכיל את שני כלי הרכב (המרה כלפי מעלה)
        
        // TODO: עברו על המערך, ועבור כל כלי רכב:
        //   - הדפיסו את התוצאה של GetBasicInfo()
        //   - השתמשו במילת המפתח 'is' עם התאמת תבניות כדי לבצע המרה בטוחה כלפי מטה:
        //     - אם הוא מסוג Car, קראו ל-Honk() והדפיסו את התוצאה
        //     - אם הוא מסוג Motorcycle, קראו ל-Rev() והדפיסו את התוצאה
    }
}
quiz iconבחנו את עצמכם

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

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

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