الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

ما هي فائدة تعدد الأوجه

مغلق
بدأه الوريد الحاسوبي في 15 يوليو 2005 · 3 رد · 3,759 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

لتعـدد الأوجـه فائدة كبيرة

على مستوى الدوال العادية

والمعاملات

لكن ماهي فائدتـه على مستـوى الكائنـات

حسب فهـمي له

أنـه بإمكاني إنشاء مؤشر إلى صنف أو كلاس أساس وأحجز له ذاكرة له من نـوع صنف أو كلاس مشتقـة منه

لكن ما هي الفائدة ؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟

#2

تعدد الاوجه او تعدد الاشكال POLYMORPHISM

تعدد الاوجه او تعدد الاشكال, ترجمتين لنفس العبارة.

ما هى الفكرة؟

اتوقع انك تجيد البرمجة كائنية المنحى بحيث انك

تعرف كيف تنشئ class و تمهد كل من ال constructor

و ال destructor و تراعى خصوصية الكائن و ثبات الواجهة

التى يعطيها للمستخدم لل class بحيث تكون مرنة , و واضحة و سهل

النعامل معها.

الان و انت بهذا القدر من المعلومات لا بد انك تعلم كيف تنشئ

نسختين من نفس الدالة بنفس الاسم , مع اختلاف المعاملات.

يعنى اذا كان عندنا كلاس تمثل list عناصر من النوع double

class list
{   
      private :
              int length;
              double *array;

     list()
    {
              length  = 0;
     }
     //////////////////////////
    /////      here add the functions as you like
     ///////////////////////////

     void Add ( double x );
     vod Add ( const list& l);

}

لاحظ معى ان هناك دالتين تحملان نفس الاسم لكن هناك اختلاف فى المعاملات

الدالتين Add التى تقبل double حتى تلحقه بال list , اما الاخرى, فهى تقبل

list حتى تضيف كل عناصرها الى الكائن الحالى , و يمكن ان تستخدم الاولى , او لا

هذه الفكرة جميلة , و هى تعطى احساس شفافية الكائن و تقبله لكل الظروف.

لا تضق بى اخى فانا لم انسى تعدد الاشكال.

ساضرب لك مثال قرأته من كتاب نظرى و انت تكتب الكود بنفسك.

تخيل انك تعمل كمبرمج لحساب احدى البنوك و كانت اللغة المستخدمة

لغة كائنية المنحى مثل ال C++ او ال java . و قام الشخص الذى يحلل البرنامج

بوضع صورة شاملة. و توزيع المهام على المبرمجين. و انت من ضمنهم. وقع الاختيار عليك

حتى تصمم ال class التى اسمها BankAccount التى تغلف الحساب المصرفى

بحيث ان كل حساب مصرفى له الاتى

1/ الرقم الذى يمثل رقم الحساب.

2/ قيمة الرصيد الحالى.

3/دوال مشيد و مهدم.

4/دوال للسحب و الايداع من و الى الحساب.

5/ اى معلومات اخرى من الممكن ان تضاف الى الحساب.

الان و بعد ان صممتها بالصورة الاتية , هذا مثال و ليس ال class الحقيقية.

class BankAccount
{
   double balance;
    ///////////////////
     ///  here add the constructor and the destructor if needed
   
    void add( double amount)
    {
          if ( amount > 0 )
                    balance += amount;

     }


    void withdraw(double amount)
     {
         // avoid mistaked adding to balance
         if( amount > 0   && balance > amount)
                      balance  = balance - amount;

     }

    double newyear()
   {
    balance *= 0.001;
    return 0.05 * balance;
   }
     
    

}

لنفترض ان هذه الكلاس يمكن ان تفى بالغرض,

و افرض ايضا ان :-

الدالة newyear يتم استعاْءها كل عام حتى تعيد قيمة الضريبة

التى سوف يتم سحبها من اللحساب كضريبة.

الان لنقل كل شئ كان سليم فى السليم.

لكن فجأه تم استدعائك من المبرمج الكبير . سيد اللمبرمجين

و قال لك :

نحن اسفين لعدم الايضاح ,

هناك عدة انواع من الحسابات.

1/ حساب جارى

2/حساب ادخار

3/ حساب استثمار

**************************

*************************

و الكثير من انواع الحسابات

و كل نوع من هذه الحسابات يعامل بمعاملة خاصة

بحيث ان الدالة new year على سبيل المثال. تتغير قيم

المعاملات فيها بصورة مختلفة على حسب نوع الحساب

ماذا سوف تعمل .

يمكن ان تنشئ classes جديدة مثل

SavingAccount

Current Account

InvestmentAccount

و كل انواع الحسابات الممكنة

و تحذف الدالة newyear من الكلاس BankAccount

و تنشئ لكل كلاس الدالة الخاصة به فى الكلاس,

بحيث ان كل هذه الكلاسات ترث ال BankAccount لكى

يشتركوا فى المتغيرات و الدوال التى توفرها BankAccount.

الان وعند نهاية السنة. لنفترض انك تحتاج الى

العديد من ال vectors حتى تخزن كل نوع فى ال vector المناسب

/////Code executed every year
//assume those variables are declared some where
//sa = saving account vector, that saves those acounts.
//ca = current account one
//ia = investment account one
for(int i =0;  sa.size(); i++)
{
     sa.newyear();
}

for(i =0; i < ca.size(); i++)
{
     ca.newyear();
}

او يمكن ان تضعهم كلهم فى vector واحد و تعمل switch على حسب

نوع الحساب ثم من بعد تعمل casting الى النوع المناسب منة الحسابات

و هكذا تنادى الدالة newyear على حسب نوع الحساب.

كل من الطريقتين ستحولان البرنامج الى اكوام من ال switch او

الى اطنان متفرقة من الدوارات . كل من الحلين غير سليم الى درجة كبيرة.

فكرة

ماذا لو كانت الدالة newyear معلنة داخل ال class BankAccount

و لاتفعل اى شئ. و يتم تجاوز هذه الدالة فى كل من هذه ال classes بحيث تطبق

بما يناسب نوع الحساب.

يعنى كيف.

بموجب قانون الوراثة. فان اى* SavingAccount هو ليس الا BankAccount*

يعنى اذا غيرنا الفكرة الى التالى:-

1/ نضع كل الحسابات فى vector واحد, من النوع BankAccount*

2/عند الاضافة الى الvector لن نحتاج الى اى نوع من الcasting

3/فى نهاية السنة نعمل loop واحد لكل الحسابات بغض النظر عن نوع الحساب.

/////Code executed every year
//assume those variables are declared some where
//ba = vector that contans all the accountsone
for(int i =0;  ba.size(); i++)
{
    ba->newyear();
}

للوهلة الاولى يمكن ان يحير هذا الكود و لكنه بسيط و يخدم الغرض

هذا ما يسمى بسحر تعدد الاشكال.

هل تصدق ان الدالة المناسبة سوف يتم استدعاؤها لكل حساب على حسب نوعه.

يعنى اذا تمت اضفة الحساب الاول بهذه الطريقة

SavingAccount*  sa = new SavingAccount();
///
//  here manipulate the account as you like
//

// add the accout to the vector of the accounts
ba.add(sa);

ستتم الامور على ما نريد.

لكن كيف يتم هذا.

للمتغير نوع معين, و هو الذى يحدد الواجهة التى يعطيها المتغير للمبرمج.

كل المتغيرات الموجودة فى ال vector لها خاصيتين, النوع الذى يعامل به المتغير,

فى هذه الحالة BankAccount , النوع الذى فى الاساس هو اصل المتغير, يختلف

هذا مع اختلاف نوع الحساب.

فى هذه الحالة. سيتم التعامل مع المتغير على حسب نوع اعلان الاولى للمتغير و ليس على حسب

الواجهة التى تعطيها الوراثة.

ارجو ان اكون قد اوضحت, و لا تتردد اذا كانت عندك المزيد من الاسئلة

#3

أشكرك شكراً جــزيلاً أخــي العـزيز

وشكراً على المساعـدة التي كنت أبحث عليها منذ زمن

#4

لا شكر على واجب, ارجو ان تكون قد استفدت ولو القليل :)

هذا الموضوع مغلق.

مواضيع مشابهة