مضى على الشبكة و يوم من العطاء.

البرمجة الكائنية (Encapsulation)

Sadell_AliSadell_Ali is verified member.

الرقابة والتنظيم
.:: الرقابة والتنظيم ::.

السمعة:

بسم الله الرحمن الرحيم

بعد أن تطرقنا في الدروس السابقة إلى مفاهيم الclass و ال struct سوف نبني عليهم مفهوم التغليف ( Encapsulation ) المهم جداً في البرمجة الكائنية فالنبدأ.

التغليف ( Encapsulation ) : عبارة عن أسلوب يمكن اتباعه لإخفاء خصائص الكلاس ( Global Variables ) و جعل الكائنات التي تُنشئها منه و الكلاسات الأخرى التي تقوم بتضمينه قادرة على التعامل مع هذه الخصائص فقط من خلال دوال يقوم بإنشائها المبرمج الأساسي للكلاس.
إذاً فائدة التغليف أنه يتيح لك وضع شروط لتخزين القيم في الخصائص, كما أنه يتيح لك الحصول على القيم بالطريقة التي تريدها .

بما أن فكرة التغليف الأساسية هي إخفاء البيانات من جهة و إتاحة التعامل معها من جهة أخرى , أول ما يجب أن يخطر في بالك هو أنه يجب جعل نوع جميع الخصائص ( أي المتغيرات التي ستحفظ البيانات ) الموجودة في الكلاس private , لأن جعلها private يعني أنه يمكن الوصول إليهم فقط من داخل الكلاس الموجودين فيه , ولتستطيع الوصول إلى هذه الخصائص من الخارج عليك تجهيز دوال نوعها public للتعامل مع هذه الخصائص وذلك لأن الدوال التي نوعها public يمكن الوصول إليهم من أي مكان.
إذاً لتحقيق مبدأ التغليف عليك جعل نوع الخصائص private
و جعل نوع الدوال التي تستخدم للوصول إليهم public

سنتحدث الآن عن دوال ال set ,وال get لنقل لأنها أكثر استخداماً ومهمة جداً حيث أنها تستخدم لأخذ القيم وإرجاعها , عند التعامل مع أي متغير فعندك خيارين وهما إما إعطاءه قيمة جديدة و إما الحصول على القيمة الموجودة فيه.
بما أنه يجب بناء دوال للتعامل مع كل خاصية من الخصائص الموجودة في الكلاس, فيُنصح بإعتماد أسماء متعارف عليها وذلك بجعل اسم الدالة هو نفسه الهدف المراد من هذه الدالة, سيتم إعطاء مثال من غير تغليف ومثال أُستخدِمَ به أسلوب التغليف

المثال الأول =>
فكرت هذا المثال أننا سنقوم بتخزين معلومات الموظفين بعدها سنقوم بإنشاء كائن من الكلاس نفسه في دالة main() و التعامل معه

كود:
#include <iostream>

using namespace std;

// يحتوي على 3 خصائص Employee هنا قمنا بتعريف كلاس إسمه
class Employee {

    public:
        string name;       // لأنه عبارة عن نص string الإسم نوعه
        int age;           // لأنه عبارة عن رقم int العمر نوعه
        double salary;     // لأنه عبارة عن رقم كبير يمكن أن يحتوي على فاصلة double الراتب نوعه
 
};

// main() هنا قمنا بتعريف الدالة
int main()
{
    // e إسمه Employee هنا قمنا بإنشاء كائن من الكلاس
    Employee e;
 
    // e هنا قمنا بإعطاء قيم لخصائص الكائن
    e.name = "Mhamad";
    e.age = 21;
    e.salary = 950;
 
    // e هنا قمنا بعرض قيم خصائص الكائن
    cout << "Name: " << e.name << "\n";
    cout << "Age: " << e.age << "\n";
    cout << "Salary: " << e.salary;
}
ستكون نتيجة الكود السابق هي👇
كود:
Name: Mhamad
Age: 21
Salary: 950
أما الآن سنقوم بإعادة المثال السابق مع جعل نوع الخصائص private و سنقوم بتعريف دوال (set و get ) نوعها public للتعامل مع هذه الخصائص
في هذا المثال سيتم تطبيق مبدأ التغليف 😊

المثال الثاني =>

كود:
#include <iostream>

using namespace std;

// Employee هنا قمنا بتعريف الكلاس
class Employee {

    // و بالتالي لم يعد ممكناً الوصول لهم بشكل مباشر من خارج الكلاس private لاحظ أننا جعلنا نوع الخصائص
    private:
        string name;
        int age;
        double salary;
      
    // حتى نستطيع من الوصول من خارج الكلاس public هنا قمنا بتعريف جميع الدوال التي سنتعامل من خلالها مع الخصائص كـ
    public:
        // name هذه الدالة ترجع قيمة المخزنة الخاصية
        string getName() {
            return name;
        }
 
        // age هذه الدالة ترجع قيمة المخزنة الخاصية
        int getAge() {
            return age;
        }
 
        // salary هذه الدالة ترجع قيمة المخزنة الخاصية
        double getSalary() {
            return salary;
        }
 
        // name هذه الدالة نعطيها إسم فتقوم بوضعه للخاصية
        void setName(string n) {
            name = n;
        }
      
        // age هذه الدالة نعطيها رقم فتقوم بوضعه للخاصية
        void setAge(int a) {
            age = a;
        }
 
        // salary هذه الدالة نعطيها رقم فتقوم بوضعه للخاصية
        void setSalary(double s) {
            salary = s;
        }
};

// main() هنا قمنا بتعريف الدالة
int main()
{
    // e إسمه Employee هنا قمنا بإنشاء كائن من الكلاس
    Employee e;
 
    // Setter من خلال دوال الـ e هنا قمنا بوضع قيم لخصائص الكائن
    e.setName("Mhamad");
    e.setAge(21);
    e.setSalary(950);
 
    // Getter من خلال دوال الـ e هنا قمنا بعرض قيم خصائص الكائن
    cout << "Name: " << e.getName() << "\n";
    cout << "Age: " << e.getAge() << "\n";
    cout << "Salary: " << e.getSalary();
}

الناتج للمثال السابق 👇

كود:
Name: Mhamad
Age: 21
Salary: 950

المثال الثالث =>
في هذا المثال سنعيد المثال السابق مع إضافة شرط على الدالة setName() يحدد أنه عند إدخال الإسم يجب أن يتألف من أكثر من حرفين
وإضافة شرط على الدالة getName() لجعلها ترجع Not defined إذا كان لا يوجد إسم مُدخل في الخاصية

كود:
#include <iostream>

using namespace std;

// Employee هنا قمنا بتعريف الكلاس
class Employee {

    // private لاحظ أننا أبقينا نوع الخصائص
    private:
        string name;
        int age;
        double salary;
      
    public:
        // name في حال لم يتم يكن هناك إسم مدخل في الخاصية "Not defined" لجعلها ترجع العبارة getName() هنا وضعنا شرط في الدالة
        string getName() {
            if (name == "")
            {
                return "Not defined";
            }
            else
            {
                return "Mr." + name;
            }
        }
 
        // لم نجري أي تعديل على هذه الدالة
        int getAge() {
            return age;
        }
 
        // لم نجري أي تعديل على هذه الدالة
        double getSalary() {
            return salary;
        }
 
        // فقط في حال كان الإسم الذي نمرره لها يتألف من أكثر من حرفين name لجعلها تقبل تخزين الإسم في الخاصية setName() هنا وضعنا شرط في الدالة
        void setName(string n) {
            if (n.length() < 3)
            {
                cout << "Name is too short, name can't be less then 3 characters!\n";
            }
            else
            {
                name = n;
            }
        }
      
        // لم نجري أي تعديل على هذه الدالة
        void setAge(int a) {
            age = a;
        }
 
        // age هذه الدالة نعطيها رقم فتقوم بوضعه للخاصية
        void setSalary(double s) {
            salary = s;
        }
};

// main() هنا قمنا بتعريف الدالة
int main()
{
    // e إسمه Employee هنا قمنا بإنشاء كائن من الكلاس
    Employee e;
 
    e.setName("dj");     // كإسم لأنه يتألف من حرفين فقط "dj" هنا لن يقبل أن ندخل
    e.setAge(21);
    e.setSalary(950);
 
    cout << "Name: " << e.getName() << "\n";    // لأن الإسم الذي أدخلناه سابقاً لم يتم قبوله "Not defined" هنا يفترض أن ترجع الدالة عبارة
    cout << "Age: " << e.getAge() << "\n";
    cout << "Salary: " << e.getSalary();
}
سنحصل على النتيجة التالية عند التشغيل👇
كود:
Name is too short, name can't be less then 3 characters!
Name: Not defined
Age: 21
Salary: 950
سنلاحظ التالي أنه لم يقبل الإسم الذي أدخلناه عن طريق الدالة setName() لأنه أصغر من ثلاثة أحرف , لذلك طبع الرسالة التي قمنا بتجهيزها في حال تم إدخال إسم أصغر من ثلاثة أحرف , وبما أنه لم يضع الإسم الذي قمنا بإدخاله في الخاصية name سنلاحظ أن الدالة getName() قامت بإرجاع القيمة Not defined والتي قمنا بتجهيزها في حال لم يتم إدخال أي إسم فيه.
بتمنى تكون وضحت الفكرة😊

🌸يعطيكم العافية 🌸

دروس البرمجة الكائنية
 
التعديل الأخير بواسطة المشرف:
بعد أن تطرقنا في الدروس السابقة إلى مفاهيم الclass و ال struct سوف نبني عليهم مفهوم التغليف ( Encapsulation ) المهم جداً في البرمجة الكائنية فالنبدأ
التغليف ( Encapsulation ) عبارة عن أسلوب يمكن اتباعه لإخفاء خصائص الكلاس ( Global Variables ) و جعل الكائنات التي تُنشئها منه و الكلاسات الأخرى التي تقوم
بتضمينه قادرة على التعامل مع هذه الخصائص فقط من خلال دوال يقوم بإنشائها المبرمج الأساسي للكلاس
إذاً ففائدة التغليف أنه يتيح لك وضع شروط لتخزين القيم في الخصائص, كما أنه يتيح لك الحصول على القيم بالطريقة التي تريدها
بما أن فكرة التغليف الأساسية هي إخفاء البيانات من جهة و إتاحة التعامل معها من جهة أخرى
أول ما يجب أن يخطر في بالك هو أنه يجب جعل نوع جميع الخصائص ( أي المتغيرات التي ستحفظ البيانات ) الموجودة في الكلاس private
لأن جعلها private يعني أنه يمكن الوصول إليهم فقط من داخل الكلاس الموجودين فيه
ولتستطيع الوصول إلى هذه الخصائص من الخارج عليك تجهيز دوال نوعها public للتعامل مع هذه الخصائص
وذلك لأن الدوال التي نوعها public يمكن الوصول إليهم من أي مكان.
إذاً لتحقيق مبدأ التغليف(عليك جعل نوع الخصائص private و جعل نوع الدوال التي تستخدم للوصول إليهم public)
سنتحدث الان عن دوال ال set ,وال get لنقل لأنها (أكثر استخداماً ومهمة جداً حيث أنها تستخدم لأخذ القيم وإرجاعها )
عند التعامل مع أي متغير فعندك خيارين و هما إما إعطاءه قيمة جديدة و إما الحصول على القيمة الموجودة فيه.
بما أنه يجب بناء دوال للتعامل مع كل خاصية من الخصائص الموجودة في الكلاس, فيُنصح بإعتماد أسماء متعارف عليها
وذلك بجعل اسم الدالة هو نفسه الهدف المراد من هذه الدالة, سيتم إعطاء مثال من غير تغليف ومثال أُستخدِمَ به أسلوب التغليف
المثال الأول =>
فكرت هذا المثال أننا سنقوم بتخزين معلومات الموظفين بعدها سنقوم بإنشاء كائن من الكلاس نفسه في دالة main() و التعامل معه
كود:
#include <iostream>

using namespace std;

// يحتوي على 3 خصائص Employee هنا قمنا بتعريف كلاس إسمه
class Employee {

    public:
        string name;       // لأنه عبارة عن نص string الإسم نوعه
        int age;           // لأنه عبارة عن رقم int العمر نوعه
        double salary;     // لأنه عبارة عن رقم كبير يمكن أن يحتوي على فاصلة double الراتب نوعه
 
};

// main() هنا قمنا بتعريف الدالة
int main()
{
    // e إسمه Employee هنا قمنا بإنشاء كائن من الكلاس
    Employee e;
 
    // e هنا قمنا بإعطاء قيم لخصائص الكائن
    e.name = "Mhamad";
    e.age = 21;
    e.salary = 950;
 
    // e هنا قمنا بعرض قيم خصائص الكائن
    cout << "Name: " << e.name << "\n";
    cout << "Age: " << e.age << "\n";
    cout << "Salary: " << e.salary;
}
ستكون نتيجة الكود السابق هي👇
كود:
Name: Mhamad
Age: 21
Salary: 950
أما الآن سنقوم بإعادة المثال السابق مع جعل نوع الخصائص private و سنقوم بتعريف دوال (set و get ) نوعها public للتعامل مع هذه الخصائص
في هذا المثال سيتم تطبيق مبدأ التغليف 😊
المثال الثاني =>
كود:
#include <iostream>

using namespace std;

// Employee هنا قمنا بتعريف الكلاس
class Employee {

    // و بالتالي لم يعد ممكناً الوصول لهم بشكل مباشر من خارج الكلاس private لاحظ أننا جعلنا نوع الخصائص
    private:
        string name;
        int age;
        double salary;
       
    // حتى نستطيع من الوصول من خارج الكلاس public هنا قمنا بتعريف جميع الدوال التي سنتعامل من خلالها مع الخصائص كـ
    public:
        // name هذه الدالة ترجع قيمة المخزنة الخاصية
        string getName() {
            return name;
        }
 
        // age هذه الدالة ترجع قيمة المخزنة الخاصية
        int getAge() {
            return age;
        }
 
        // salary هذه الدالة ترجع قيمة المخزنة الخاصية
        double getSalary() {
            return salary;
        }
 
        // name هذه الدالة نعطيها إسم فتقوم بوضعه للخاصية
        void setName(string n) {
            name = n;
        }
       
        // age هذه الدالة نعطيها رقم فتقوم بوضعه للخاصية
        void setAge(int a) {
            age = a;
        }
 
        // salary هذه الدالة نعطيها رقم فتقوم بوضعه للخاصية
        void setSalary(double s) {
            salary = s;
        }
};

// main() هنا قمنا بتعريف الدالة
int main()
{
    // e إسمه Employee هنا قمنا بإنشاء كائن من الكلاس
    Employee e;
 
    // Setter من خلال دوال الـ e هنا قمنا بوضع قيم لخصائص الكائن
    e.setName("Mhamad");
    e.setAge(21);
    e.setSalary(950);
 
    // Getter من خلال دوال الـ e هنا قمنا بعرض قيم خصائص الكائن
    cout << "Name: " << e.getName() << "\n";
    cout << "Age: " << e.getAge() << "\n";
    cout << "Salary: " << e.getSalary();
}

الناتج للمثال السابق 👇

كود:
Name: Mhamad
Age: 21
Salary: 950
المثال الثالث =>
في هذا المثال سنعيد المثال السابق مع إضافة شرط على الدالة setName() يحدد أنه عند إدخال الإسم يجب أن يتألف من أكثر من حرفين
و إضافة شرط على الدالة getName() لجعلها ترجع Not defined إذا كان لا يوجد إسم مُدخل في الخاصية
كود:
#include <iostream>

using namespace std;

// Employee هنا قمنا بتعريف الكلاس
class Employee {

    // private لاحظ أننا أبقينا نوع الخصائص
    private:
        string name;
        int age;
        double salary;
       
    public:
        // name في حال لم يتم يكن هناك إسم مدخل في الخاصية "Not defined" لجعلها ترجع العبارة getName() هنا وضعنا شرط في الدالة
        string getName() {
            if (name == "")
            {
                return "Not defined";
            }
            else
            {
                return "Mr." + name;
            }
        }
 
        // لم نجري أي تعديل على هذه الدالة
        int getAge() {
            return age;
        }
 
        // لم نجري أي تعديل على هذه الدالة
        double getSalary() {
            return salary;
        }
 
        // فقط في حال كان الإسم الذي نمرره لها يتألف من أكثر من حرفين name لجعلها تقبل تخزين الإسم في الخاصية setName() هنا وضعنا شرط في الدالة
        void setName(string n) {
            if (n.length() < 3)
            {
                cout << "Name is too short, name can't be less then 3 characters!\n";
            }
            else
            {
                name = n;
            }
        }
       
        // لم نجري أي تعديل على هذه الدالة
        void setAge(int a) {
            age = a;
        }
 
        // age هذه الدالة نعطيها رقم فتقوم بوضعه للخاصية
        void setSalary(double s) {
            salary = s;
        }
};

// main() هنا قمنا بتعريف الدالة
int main()
{
    // e إسمه Employee هنا قمنا بإنشاء كائن من الكلاس
    Employee e;
 
    e.setName("dj");     // كإسم لأنه يتألف من حرفين فقط "dj" هنا لن يقبل أن ندخل
    e.setAge(21);
    e.setSalary(950);
 
    cout << "Name: " << e.getName() << "\n";    // لأن الإسم الذي أدخلناه سابقاً لم يتم قبوله "Not defined" هنا يفترض أن ترجع الدالة عبارة
    cout << "Age: " << e.getAge() << "\n";
    cout << "Salary: " << e.getSalary();
}
سنحصل على النتيجة التالية عند التشغيل👇
كود:
Name is too short, name can't be less then 3 characters!
Name: Not defined
Age: 21
Salary: 950
سنلاحظ التالي أنه لم يقبل الإسم الذي أدخلناه عن طريق الدالة setName() لأنه أصغر من ثلاثة أحرف
لذلك طبع الرسالة التي قمنا بتجهيزها في حال تم إدخال إسم أصغر من ثلاثة أحرف
و بما أنه لم يضع الإسم الذي قمنا بإدخاله في الخاصية name سنلاحظ أن الدالة getName()
قامت بإرجاع القيمة Not defined والتي قمنا بتجهيزها في حال لم يتم إدخال أي إسم فيه
بتمنى تكون وضحت الفكرة😊
🌸يعطيكم العافية 🌸
الله يعطيكِ الف عافيه سديل وبارك الله فيكِ
ننتظر جديدك دائماً بإذن الله
 
بارك الله فيك يا سديل، استمري ❤️
 

آخر المشاركات

فانوس

رمضان
عودة
أعلى