Menu
Coddy logo textTech

דריסת מתודות

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C++ של Coddy. שיעור 51 מתוך 104.

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

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

class Animal {
public:
    void speak() {
        std::cout << "Some sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void speak() {
        std::cout << "Woof!" << std::endl;
    }
};

Dog d;
d.speak();  // פלט: Woof!

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

class Dog : public Animal {
public:
    void speak() {
        Animal::speak();  // קרא לגרסה של מחלקת הבסיס
        std::cout << "Woof!" << std::endl;
    }
};

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

Dog d;
Animal* ptr = &d;
ptr->speak();  // פלט: צליל כלשהו (לא Woof!)

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

challenge icon

אתגר

קל

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

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

  • Notifier.h: הגדירו מחלקת בסיס Notifier עם:
    • שדה std::string recipient מוגן
    • בנאי שמקבל את שם הנמען ושומר אותו
    • מתודת send(const std::string& message) ציבורית שמדפיסה: Sending to <recipient>: <message>
  • EmailNotifier.h: הגדירו מחלקת EmailNotifier שיורשת באופן ציבורי מ־Notifier:
    • בנאי שמקבל נמען ומעביר אותו למחלקת הבסיס
    • החליפו את מימוש המתודה send() כך שקודם תקרא לגרסה של מחלקת הבסיס באמצעות Notifier::send(), ואז תדפיס: [Email sent successfully]
  • main.cpp: קראו שני קלטים (כל אחד בשורה נפרדת):
    1. שם הנמען (מחרוזת)
    2. תוכן ההודעה (מחרוזת)

    הגדירו מחלקת SMSNotifier ישירות בתוך main.cpp, שיורשת באופן ציבורי מ־Notifier:

    • בנאי שמקבל נמען ומעביר אותו למחלקת הבסיס
    • החליפו את מימוש המתודה send() כך שתדפיס: SMS to <recipient>: <message> (ותחליף לחלוטין את ההתנהגות של מחלקת הבסיס בלי לקרוא לה)

    צרו אובייקט אחד מכל סוג של התראה (מחלקת הבסיס Notifier, המחלקה EmailNotifier והמחלקה SMSNotifier) באמצעות אותו נמען. קראו ל־send() בכל אחד מהם עם הודעת הקלט, והדפיסו שורת הפרדה בין כל אחד:

    --- Base Notifier ---
    <output>
    --- Email Notifier ---
    <output>
    --- SMS Notifier ---
    <output>

לדוגמה, עבור הקלטים Alice ו־Hello there!:

--- Base Notifier ---
Sending to Alice: Hello there!
--- Email Notifier ---
Sending to Alice: Hello there!
[Email sent successfully]
--- SMS Notifier ---
SMS to Alice: Hello there!

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

נסו בעצמכם

#include <iostream>
#include <string>
#include "Notifier.h"
#include "EmailNotifier.h"

using namespace std;

// TODO: הגדירו כאן מחלקה SMSNotifier שיורשת באופן ציבורי מ-Notifier
// - בנאי שמעביר את recipient למחלקת הבסיס
// - דרסו את send() כך שתדפיס: SMS to <recipient>: <message>
//   (החליפו לחלוטין את התנהגות הבסיס, אל תקראו ל-send() של מחלקת האב)

int main() {
    string recipient;
    string message;
    
    getline(cin, recipient);
    getline(cin, message);
    
    // TODO: צרו אובייקט Notifier עם recipient
    // הדפיסו "--- Base Notifier ---"
    // קראו ל-send() עם message
    
    // TODO: צרו אובייקט EmailNotifier עם recipient
    // הדפיסו "--- Email Notifier ---"
    // קראו ל-send() עם message
    
    // TODO: צרו אובייקט SMSNotifier עם recipient
    // הדפיסו "--- SMS Notifier ---"
    // קראו ל-send() עם message
    
    return 0;
}
quiz iconבחנו את עצמכם

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

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

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