Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

مستويات الوصول في الوراثة

جزء من قسم Object Oriented Programming في رحلة C++ على Coddy — الدرس 49 من 104.

يؤثر نوع الـ inheritance الذي تختاره على كيفية الوصول إلى أعضاء الـ base class في الـ derived class. توفر لغة C++ ثلاثة خيارات: public، و protected، و private inheritance.

إليك كيف يحول كل نوع access الأعضاء:

عضو Basepublic inheritanceprotected inheritanceprivate inheritance
publicpublicprotectedprivate
protectedprotectedprotectedprivate
privateinaccessibleinaccessibleinaccessible
class Base {
public:
    int pub;
protected:
    int prot;
private:
    int priv;
};

class PublicDerived : public Base {
    // pub هو public، prot هو protected، priv غير قابل للوصول
};

class ProtectedDerived : protected Base {
    // pub هو protected، prot هو protected، priv غير قابل للوصول
};

class PrivateDerived : private Base {
    // pub هو private، prot هو private، priv غير قابل للوصول
};

تنمذج الوراثة العامة (Public inheritance) علاقات "is-a" وهي الأكثر شيوعًا بفارق كبير. الكلب Dog هو حيوان Animal، لذا يمكن للكود الخارجي التعامل معه على هذا الأساس.

نموذج الـ Protected and private inheritance يمثل علاقات "implemented-in-terms-of". فهي تخفي واجهة الـ Base class عن الكود الخارجي، وهو أمر مفيد عندما تريد إعادة استخدام التنفيذ دون إظهار علاقة الـ inheritance. ومع الـ private inheritance، تفقد حتى الفئات الـ derived الأبعد الـ access إلى أعضاء الـ Base الأصليين.

challenge icon

التحدي

سهل

دعنا نستكشف كيف تؤثر أنواع الـ inheritance المختلفة على إمكانية الـ access للأعضاء لبناء تسلسل هرمي بسيط للأجهزة. ستنشئ كلاس Base باسم Device وثلاثة كلاسات derived، يستخدم كل منها نوع inheritance مختلفاً، لترى بنفسك كيف يغير الـ public والـ protected والـ private inheritance من إمكانية الوصول للأعضاء.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • Device.h: قم بتعريف كلاس Base باسم Device يحتوي على ثلاثة أعضاء بمستويات access مختلفة:
    • عضو public من نوع std::string model
    • عضو protected من نوع int serialNumber
    • عضو private من نوع int internalCode (بقيمة افتراضية 999)
    • method نوعه public باسم showModel() يقوم بـ print: Model: <model>

    ثم أنشئ ثلاثة كلاسات derived يورث كل منها من Device باستخدام أنواع inheritance مختلفة:

    • PublicDevice باستخدام public inheritance — أضف method باسم displaySerial() يقوم بـ print: Serial: <serialNumber>
    • ProtectedDevice باستخدام protected inheritance — أضف method باسم displaySerial() يقوم بـ print: Serial: <serialNumber>
    • PrivateDevice باستخدام private inheritance — أضف method باسم displaySerial() يقوم بـ print: Serial: <serialNumber>

    يجب أن يحتوي كل كلاس derived على Constructor يأخذ اسم الـ model و الـ serialNumber، مع إرسال الـ model إلى الكلاس الـ Base وتحديد الـ serialNumber.

  • main.cpp: اقرأ مدخلين (كلاهما في سطر منفصل):
    1. اسم الـ Model (سلسلة نصية)
    2. الـ Serial number (عدد صحيح)

    أنشئ object واحداً من كل نوع derived باستخدام نفس قيم الـ input. ثم قم بـ Demonstrate لاختلافات الـ access:

    بالنسبة لـ PublicDevice:

    • قم بـ Call لـ showModel() directly على الـ object (يعمل لأن الـ public inheritance يبقيه accessible بشكل عام)
    • قم بالوصول directly إلى model واطبع: Direct model access: <model>
    • قم بـ Call لـ displaySerial()

    بالنسبة لـ ProtectedDevice و PrivateDevice:

    • قم بـ Call لـ displaySerial() فقط (حيث أن showModel() الموروثة و model لم يعودا accessible بشكل علني من الخارج)

    تنسيق المخرجات:

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

على سبيل المثال، مع الـ input التالي Laptop و 12345:

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

لاحظ كيف يسمح PublicDevice فقط بالوصول الـ external لأعضاء الـ public الموروثة. تخفي أنواع الـ inheritance الأخرى واجهة الكلاس الـ Base عن الكود الخارجي، ولكن لا يزال بإمكان الكلاسات الـ derived الوصول إلى الأعضاء الـ protected داخلياً من خلال الـ method الخاصة بها.

جرّب بنفسك

#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: Demonstrate PublicDevice access
    cout << "--- PublicDevice ---" << endl;
    // - استدعِ showModel() مباشرة على الكائن
    // - Access model directly and print: Direct model access: <model>
    // - استدعِ displaySerial()
    
    // TODO: Demonstrate ProtectedDevice access
    cout << "--- ProtectedDevice ---" << endl;
    // - استدعِ displaySerial() فقط (showModel و model غير قابلين للوصول بشكل عام)
    
    // TODO: Demonstrate PrivateDevice access
    cout << "--- PrivateDevice ---" << endl;
    // - استدعِ displaySerial() فقط (showModel و model غير قابلين للوصول بشكل عام)
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming