Menu
Coddy logo textTech

דריסת מתודות (בזמן ריצה)

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

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

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

public class Animal {
    public void speak() {
        System.out.println("Some sound");
    }
}

public class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Bark!");
    }
}

public class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Meow!");
    }
}

עכשיו נבחן מה קורה כשמשתמשים בהפניות מהסוג של מחלקת האב:

Animal myPet = new Dog();
myPet.speak();  // פלט: Bark!

myPet = new Cat();
myPet.speak();  // פלט: Meow!

למרות ש־myPet מוכרז כ־Animal, ‏Java מפעילה בזמן ריצה את המתודה שנדרסה בהתבסס על סוג האובייקט בפועל. זה נקרא שליחת מתודות דינמית. ה־JVM בוחנת מהו האובייקט בפועל, ולא מה שהמשתנה מציין.

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

Animal[] pets = {new Dog(), new Cat(), new Dog()};
for (Animal pet : pets) {
    pet.speak();  // כל אחד קורא לגרסה משלו
}

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

challenge icon

אתגר

קל

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

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

  • Notification.java: צרו מחלקת בסיס שמשותפת לכל ההתראות. לכל התראה יש שדה recipient (String). כללו בנאי לאתחול שלו, מתודת getter ומתודת send() שמדפיסה: Sending notification to [recipient]
  • EmailNotification.java: צרו מחלקה שמרחיבה את Notification. התראות דוא״ל מוסיפות שדה subject. השתמשו ב-super לאתחול מחלקת האב. דרסו את המתודה send() כדי להדפיס: Emailing [recipient]: [subject]
  • SMSNotification.java: צרו מחלקה נוספת שמרחיבה את Notification. התראות SMS מוסיפות שדה phoneNumber. דרסו את send() כדי להדפיס: Texting [phoneNumber] for [recipient]
  • Main.java: כאן הפולימורפיזם בזמן ריצה בא לידי ביטוי! תקבלו שלוש קלטים: שם נמען, נושא של הודעת דוא״ל ומספר טלפון. צרו מערך של הפניות מסוג Notification המכיל שלושה אובייקטים בסדר הזה: Notification בסיסי,‏ EmailNotification ו-SMSNotification (כולם עם אותו נמען). לאחר מכן עברו בלולאה על המערך וקראו ל-send() בכל איבר. שימו לב איך Java קוראת אוטומטית לגרסה הנכונה שנדרסה, בהתאם לסוג האובייקט בפועל!

תקבלו שלוש קלטים: שם הנמען (String), נושא הודעת הדוא״ל (String) ומספר הטלפון (String).

הפלט שלכם צריך להציג שלוש שורות - כל קריאה ל-send() מפיקה פלט שונה, אף שאתם קוראים לאותה מתודה דרך הפניות מסוג Notification. כך פועלת שליחת מתודות דינמית!

נסו בעצמכם

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // קראו את הקלטים
        String recipient = scanner.nextLine();
        String subject = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        
        // TODO: צרו מערך של הפניות ל-Notification עם 3 איברים
        // המערך צריך להכיל (בסדר הזה):
        // 1. אובייקט בסיסי מסוג Notification
        // 2. אובייקט מסוג EmailNotification
        // 3. אובייקט מסוג SMSNotification
        // כולם משתמשים באותו נמען
        
        // TODO: עברו על המערך וקראו ל-send() עבור כל איבר
        // כך מודגמת פולימורפיות בזמן ריצה!
    }
}
quiz iconבחנו את עצמכם

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

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

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