إعلان
دورة تطوير التطبيقات باستخدام لغة JavaScript في هذه الدورة ستتعلم لغة جافا سكريبت, استخدام مكتبة React.js, بناء API الموقع بواسطة Node.js, تطوير تطبيق جوال باستخدام React Native, و في نهاية الدورة ستتعلم تطوير تطبيق محادثة شبيه بتطبيق WhatsApp. تعلم الآن
دورة تطوير واجهات المستخدم في هذه الدورة ستتعلم لغة HTML و لغة CSS و لغة JavaScript. من ناحية التطبيق العملي ستتعلم طريقة بناء واجهة متجر إلكتروني مكون من ست صفحات, تحويل خمسة تصاميم PSD إلى صفحات ويب, بناء واجهة مستخدم تشبه موقع يوتيوب, بناء لوحة تحكم إحترافية. تعلم الآن
تطوير تطبيقات باستخدام لغة بايثون في هذه الدورة ستتعلم أساسيات البرمجة بلغة بايثون وصولاً إلى التعامل مع أشهر أطر العمل (Flask و Django) و ستتعلم كيف تبني متجر إلكتروني يمكن للمستخدمين البيع و الشراء من خلاله. تعلم الآن
دورة تطوير تطبيقات الويب باستخدام لغة PHP في هذه الدورة ستتعلم لغة PHP من الصفر, استخدام إطار العمل Laravel بشرح مفصّل و عملي, كيفية تطوير شبكة اجتماعية تشبه Instagram, بناء API لتطبيق جوال وفق أسلوب RESTful, تطوير موقع إعلانات مبوبة, تطوير نظام إدارة محتوى CMS كامل. تعلم الآن
دورة تطوير تطبيقات الويب باستخدام لغة Ruby في هذه الدورة ستتعلم البرمجة بلغة Ruby إنطلاقاً من أبسط المفاهيم وحتى بناء تطبيق حقيقي, إستخدام إطار العمل Ruby on Rails بشرح مفصّل و عملي, بناء تطبيق حقيقي عبارة عن شبكة اجتماعية تشبه تويتر, تطوير مجتمع الكتروني يشبه حسوب I/O. تعلم الآن
دورة علوم الحاسوب هذه الدورة معدة لتكون مدخل لعلوم الحاسوب و لغات البرمجة حيث ستتعرف فيها على أنظمة التشغيل و ستتعمق في نظام لينكس و في كيفية التعامل معه من خلال موجه الأوامر, بالإضافة إلى قواعد البيانات و أساسيات الشبكات و الخوادم و مبادئ الحماية والأمان في الويب. تعلم الآن

    C++ Overriding

    مفهوم إعادة التعريف

    في الدرس السابق, شاهدت كيف أنه عندما يرث الكلاس من كلاس آخر فإنه يرث المتغيرات و الدوال الموجودة فيه.

    إعادة التعريف أو التعريف من جديد ( Overriding ) تعني تعريف نفس الدالة التي ورثها الكلاس الإبن من الكلاس الأب من جديد, و هذه الدالة الجديدة تكون مشابهة للدالة الموروثة من حيث الشكل فقط, أي لها نفس الإسم و النوع و عدد الباراميترات, لكن محتواها مختلف بهدف أن يكون متناسب أكثر مع الكلاس الإبن.

    الهدف الحقيقي من إعادة التعريف أو التعريف من جديد هو إتاحة الفرصة للكلاس الإبن ليعرّف الدوال حسب حاجته.
    في دروس متقدمة سنرث من كلاسات جاهزة في C++, و نفعل Override للدوال الموجودة فيها لكي تناسب التطبيقات التي سنقوم ببنائها.


    شروط إعادة تعريف الدوال الموروثة

    • يجب أن يكون الـ Modifier المستخدم للدالة الجديدة هو نفسه المستخدم للدالة القديمة, و يجب أن يكون نوعه public أو protected.
    • عدد و نوع باراميترات الدالة الجديدة يجب أن يطابق عدد و نوع باراميترات الدالة القديمة.
    • نوع الإرجاع للدالة الجديدة يجب أن يكون نفس نوع الإرجاع للدالة القديمة.
    • الدالة المعرفة كـ private لا يمكن أن نفعل لها Override, لأن كلمة private تمنع إمكانية الوصول المباشر للدالة من الكلاس الإبن.
    • الدالة المعرفة كـ final لا يمكن أن نفعل لها Override, لأن كلمة final تمنع تغير محتوى الدالة بعد تعريفها.
    • الدالة المعرفة كـ static لا يمكن أن نفعل لها Override و لكن يمكن تعريفها من جديد في أي مكان, لأن كلمة static تجعل الدالة مشتركة بين جميع الكلاسات.
    • لا يمكن أن نفعل Override للكونستركتور.

    مثال يوضح فائدة إعادة تعريف الدوال

    في المثال التالي قمنا بتعريف كلاس إسمه Country يعتبر الكلاس الأساسي لأي بلد.
    في هذا الكلاس قمنا بتعريف دالة إسمها language() فكرتها طباعة لغة البلد و جعلناها تطبع اللغة الإنجليزية بشكل إفتراضي كلغة أي بلد.

    بعدها قمنا بتعريف ثلاث كلاسات تمثل ثلاث بلدان مختلفة (أستراليا, لبنان, إسبانيا) لذلك جعلناها ترث من الكلاس Country الذي يعتبر أساس أي بلد.
    إذاً الكلاسات الثلاثة سترث الدالة language().

    هنا الفكرة التي نريد إيصالها هي أن أي كلاس يرث من Country قد يضطر إلى تعريف الدالة language() من جديد حتى تناسبه.
    فمثلاً لبنان لغته هي العربية, و إسبانيا لغتها هي الإسبانية.

    بعد إنشاء هذه الكلاسات, قمنا بإنشاء كائنات منها و استدعاء الدالة language() من كل واحد فيهم لطباعة اللغة التي يتكلمها الناس فبه.

    مثال

    main.cpp
    #include <iostream>
    
    using namespace std;
    
    // الذي يعتبر الكلاس الأساسي لأي دولة في العالم, إذاً يجب أن يرثه كل كلاس يمثل دولة Country هنا قمنا بتعريف الكلاس
    class Country {
    
    	// هنا قمنا بتعريف دالة تقوم بطباعة لغة البلد و جعلناها تطبع اللغة الإنجليزية كاللغة الإفتراضية لأي بلد
        public:
            void language()
            {
                cout << "English \n";
            }
    
    };
    
    
    // Country و يرث من الكلاس Australia هنا قمنا بتعريف كلاس يمثل دولة أستراليا و إسمه
    class Australia : public Country {
    	
    	// من جديد لأن اللغة الإنجليزية هي لغة أستراليا أصلاً language() هنا لا داعي لتعريف الدالة
    
    };
    
    
    // Country و يرث من الكلاس Lebanon هنا قمنا بتعريف كلاس يمثل دولة لبنان و إسمه
    class Lebanon : public Country {
    
    	// من جديد لأن اللغة الإنجليزية ليست لغة لبنان language() هنا يجب تعريف الدالة
        public:
            void language()
            {
                cout << "Arabic \n";
            }
    
    };
    
    
    // Country و يرث من الكلاس Spain هنا قمنا بتعريف كلاس يمثل دولة إسبانيا و إسمه
    class Spain : public Country {
    
    	// من جديد لأن اللغة الإنجليزية ليست لغة إسبانيا language() هنا يجب تعريف الدالة
        public:
            void language()
            {
                cout << "Spanish \n";
            }
    
    };
    
    
    // main() هنا قمنا بتعريف الدالة
    int main()
    {
        // هنا قمنا بإنشاء كائنات من البلدان الثلاثة
        Australia au;
        Lebanon lb;
        Spain sp;
    
        // لعرض لغة كل بلد language() هنا قمنا باستدعاء الدالة
        au.language();
        lb.language();
        sp.language();
    
        return 0;
    }
    		

    سنحصل على النتيجة التالية عند التشغيل.

    English
    Arabic
    Spanish 
    		


    أنت الآن فهمت لما قد تحتاج أن تفعل Override.
    سنقوم الآن بشرح طريقة عمل المترجم عندما فعلنا Override للدالة language().

    إذا عدت للكلاس Lebanon, ستجد أننا فعلنا Override للدالة language().
    إذاً هنا أصبح الكلاس Lebanon فعلياً يملك دالتين إٍسمهما language(), الأولى هي التي ورثها من الكلاس Country و الثانية هي التي قمنا بتعريفها فيه.


    بما أن الكلاس Lebanon يملك دالتين لهما نفس الإسم, النوع و عدد البارامتيرات, كيف عرف المترجم أي دالة يختار؟

    عندما قمنا بتعريف الدالة language() من جديد في الكلاس Lebanon (أي الكلاس الإبن) قام المترجم بإخفاء الدالة الأصلية التي ورثها من الكلاس Country (أي الكلاس الأب) و أظهر الدالة الجديدة فقط.


    ملاحظة

    داخل الكلاس Lebanon, لا يزال بإمكانك إستخدام الدالة language() الموجودة في الكلاس Country و التي قام المترجم بإخفائها عندما قمنا بتعريفها من جديد و هذا ما سنتعرف عليه في المثال التالي.

    مفاهيم مهمة حول إعادة تعريف الدوال


    المفهوم الأول

    لاحظنا قبل قليل أنه عند إعادة تعريف الدالة التي ورثها الكلاس الإبن من الكلاس الأب أن المترجم يقوم بإخفاء الدالة التي ورثها الكلاس الإبن و إظهار التي تم تعريفها فيه, و لكننا قلنا بأن الدالة الموجودة في الكلاس الأب لا يزال بإمكان الكلاس الإبن أن يصل إليها حتى و لو كان قد تم إخفاؤها و هذا ما سنتعلمه من هذا المثال.
    هنا وضعنا مثال حول كيفية كيفية استدعاء الدالة الموجودة في الكلاس الأب.

    شاهد المثال »



    المفهوم الثاني

    إذا كنت تريد كتابة الكود بشكل يكون سهل التعامل معه و مراجعته لاحقاً فمن الأفضل إضافة الكلمة virtual لأي دالة تريد من الكلاس الذي يرثها أن يقوم بإعادة تعريفها حتى تتناسب معه, و في الكلاس الذي يرثها من الأفضل أيضاً أن تضيف الكلمة override للدالة التي تعيد تعريفها من جديد في الكلاس الإبن.

    شاهد المثال »



    المفهوم الثالث

    إذا كنت تريد تعريف شكل الدالة ( Prototype ) فقط في الكلاس و إجبار أي كلاس يرثها على أن يقوم بتعريفها فيمكنك إستخدام الكلمة virtual لتحقيق ذلك.
    أسلوب كتابة الكود المتبع في هذا المثال يقال له التجريد ( Abstraction ).

    شاهد المثال »



    المفهوم الرابع

    إذا كنت تريد منع الكلاس الإبن من إعادة تعريف الدالة التي ورثها من الكلاس فيمكنك جعل نوع الدالة virtual final حتى أنه يمكنك جعل نوع الكلاس بأكمله final لا يمكن إعادة تعريف أي دالة موجودة فيه بهدف أن يتم استخدام الدوال الموجودة فيه كما هي.

    شاهد المثال »

    إعلان

    Eqla3Tech.com

    شروحات مكتوبة حول لغات البرمجة و تقنية المعلومات باللغة العربية مقدمة من إقلاع تك.

    لغة جافا لغة ++C قواعد البيانات نظام ويندوز نظام لينكس الشبكات تقنية المعلومات الأمن السيبراني

    الدورات

    أدوات مساعدة

    الأقسام

    دورات
    مقالات أسئلة مشاريع كتب