Menu
Coddy logo textTech

רמות גישה בירושה

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

סוג הירושה שתבחר משפיע על האופן שבו ניתן לגשת לחברי מחלקת הבסיס במחלקה הנגזרת. ב-C++ יש שלוש אפשרויות: ירושה public, ירושה protected וירושה private.

כך כל סוג משנה את הגישה לחברים:

חבר במחלקת הבסיסירושה publicירושה protectedירושה private
publicpublicprotectedprivate
protectedprotectedprotectedprivate
privateלא נגישלא נגישלא נגיש
class Base {
public:
    int pub;
protected:
    int prot;
private:
    int priv;
};

class PublicDerived : public Base {
    // pub הוא ציבורי, prot הוא מוגן, priv אינו נגיש
};

class ProtectedDerived : protected Base {
    // pub הוא מוגן, prot הוא מוגן, priv אינו נגיש
};

class PrivateDerived : private Base {
    // pub הוא פרטי, prot הוא פרטי, priv אינו נגיש
};

ירושה ציבורית מדגמלת קשרי "הוא-סוג-של", והיא הנפוצה ביותר בפער ניכר. Dog הוא Animal, ולכן קוד חיצוני יכול להתייחס אליו ככזה.

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

challenge icon

אתגר

קל

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

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

  • Device.h: הגדר מחלקת בסיס Device עם שלושה חברים ברמות גישה שונות:
    • std::string model ציבורי
    • int serialNumber מוגן
    • int internalCode פרטי (מוגדר כברירת מחדל ל־999)
    • מתודה ציבורית showModel() שמדפיסה: Model: <model>

    לאחר מכן, צור שלוש מחלקות נגזרות, שכל אחת יורשת מ־Device באמצעות סוג ירושה שונה:

    • PublicDevice עם ירושה ציבורית: הוסף מתודה displaySerial() שמדפיסה: Serial: <serialNumber>
    • ProtectedDevice עם ירושה מוגנת: הוסף מתודה displaySerial() שמדפיסה: Serial: <serialNumber>
    • PrivateDevice עם ירושה פרטית: הוסף מתודה displaySerial() שמדפיסה: Serial: <serialNumber>

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

  • main.cpp: קרא שתי קלטים (כל אחד בשורה נפרדת):
    1. שם הדגם (מחרוזת)
    2. מספר סידורי (מספר שלם)

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

    עבור PublicDevice:

    • קרא ישירות ל־showModel() באובייקט (הפעולה מצליחה כי ירושה ציבורית משאירה אותו ציבורי)
    • גש ישירות אל model והדפס: Direct model access: <model>
    • קרא ל־displaySerial()

    עבור ProtectedDevice ו־PrivateDevice:

    • קרא רק ל־displaySerial() (אי אפשר עוד לגשת מבחוץ באופן ציבורי אל showModel() ואל model שעברו בירושה)

    פורמט הפלט:

    --- PublicDevice ---
    Model: <model>
    Direct model access: <model>
    Serial: <serial>
    --- ProtectedDevice ---
    Serial: <serial>
    --- PrivateDevice ---
    Serial: <serial>

לדוגמה, עם הקלטים Laptop ו־12345:

--- PublicDevice ---
Model: Laptop
Direct model access: Laptop
Serial: 12345
--- ProtectedDevice ---
Serial: 12345
--- PrivateDevice ---
Serial: 12345

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

נסו בעצמכם

#include <iostream>
#include <string>
#include "Device.h"

using namespace std;

int main() {
    // קרא את הקלט
    string modelName;
    int serialNum;
    
    getline(cin, modelName);
    cin >> serialNum;
    
    // TODO: צור אובייקטים מכל טיפוס נגזר באמצעות ערכי הקלט
    // PublicDevice pubDev(modelName, serialNum);
    // ProtectedDevice protDev(modelName, serialNum);
    // PrivateDevice privDev(modelName, serialNum);
    
    // TODO: הדגם גישה ל-PublicDevice
    cout << "--- PublicDevice ---" << endl;
    // - קרא ל-showModel() ישירות על האובייקט
    // - גש ישירות ל-model והדפס: Direct model access: <model>
    // - קרא ל-displaySerial()
    
    // TODO: הדגם גישה ל-ProtectedDevice
    cout << "--- ProtectedDevice ---" << endl;
    // - קרא רק ל-displaySerial() (הגישה ל-showModel ול-model אינה ציבורית)
    
    // TODO: הדגם גישה ל-PrivateDevice
    cout << "--- PrivateDevice ---" << endl;
    // - קרא רק ל-displaySerial() (הגישה ל-showModel ול-model אינה ציבורית)
    
    return 0;
}
quiz iconבחנו את עצמכם

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

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

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