تعدد الأشكال
يعد تعدد الأشكال إحدى السمات المهمة للبرمجة الشيئية، ويمكن فهم المعنى الحرفي ببساطة على النحو التالي: أشكال متعددة، ومظاهر متعددة. في الواقع، المعنى الأساسي هو نفسه في البرمجة الموجهة للكائنات، وهذا يعني أن نفس الطريقة سيكون لها تأثيرات تنفيذ مختلفة عند تنفيذها بواسطة كائنات مختلفة.
على وجه التحديد، يمكن تقسيم تنفيذ تعدد الأشكال إلى نوعين: تعدد الأشكال في وقت الترجمة وتعدد الأشكال في وقت التشغيل. الأول هو عملية التشغيل المحددة التي يتم تحديدها عند التجميع، والأخير هو عملية التشغيل التي يتم تحديدها فقط أثناء تشغيل البرنامج. يعتبر تحديد عملية التشغيل هذا ملزمًا ، ويُعرف أيضًا باسم الارتباط .
يسمى الارتباط الذي تم تأكيده أثناء التجميع والاتصال بالربط الثابت . ويندرج التحميل الزائد للوظيفة وإنشاء مثيل لقوالب الوظائف التي تعلمناها سابقًا في هذه الفئة. والآخر هو تأكيد أي جزء من التعليمات البرمجية يتم تنفيذه أثناء التشغيل، وهو ما يسمى الربط الديناميكي . في هذه الحالة، لا يمكن تأكيد أي جزء من التعليمات البرمجية يتم تنفيذه عند التجميع، ولكن لا يمكن تأكيده إلا بعد إنشاء البرنامج. يجري.
بالمقارنة بين الاثنين، فإن الربط الثابت قد حدد بالفعل كيفية تنفيذه أثناء التجميع، لذلك فهو فعال في التنفيذ بينما يجب أن يكون الربط الديناميكي أبطأ، ولكن ميزته هي المرونة. كلاهما لهما مزاياهما الخاصة وسيناريوهات الاستخدام المختلفة.
أدناه، سنقدم لك مثالًا بسيطًا حول الارتباط الثابت:
/***************************: /حقوق النشر:www.dotcpp.com//التاريخ:2017/12/20********************************* *** *******/#include<iostream>usingnamespacestd;#definePI3.1415926classPoint{private:intx,y;public:Point(intx=0,inty=0){this->x=x;this ->y =y;}doublearea(){return0.0;}};classCircle:publicPoint{private:intr;public:Circle(intx,inty,intR):Point(x,y){r=R;}doublearea (){ returnPI*r*r;}};intmain(){PointA(10,10);cout<<A.area()<<endl;CircleB(10,10,20);cout<<B.area ()< <endl;Point*p;p=&B;cout<<p->area()<<endl;Point&pp=B;cout<<pp.area()<<endl;return0;}
تم تعريف فئتين، فئة النقطة وفئة الدائرة المشتقة. يمكنك رؤية كود الوظيفة الرئيسية ونتائج منطقة الإخراج الأربعة كما يلي:
يمكنك مقارنة الكود لفهم المخرجات الأربعة:
يقوم cout الأول بإخراج مساحة A، وهي طريقة المنطقة في فئة Point، المنطقة 0، لذلك لا توجد مشكلة.
يقوم cout الثاني بإخراج مساحة B، ومن الواضح أن هذه هي طريقة المساحة لدائرة الفئة المشتقة، ويتم حساب المساحة بشكل طبيعي وفقًا للصيغة والقيمة هي 1256.64، وهي ليست مشكلة.
يقوم cout الثالث بإخراج طريقة المنطقة لكائن فئة الدائرة المشار إليها بواسطة مؤشر نوع النقطة p، ويخرج 0، وهو ما يمثل بوضوح طريقة المنطقة في فئة النقطة. ما تنفذه لغة C++ هنا هو الربط الثابت، أي أنه عند الترجمة، فإنه يحدد المنطقة التي سيتم تنفيذها بناءً على نوع p، لذا فهو 0.
يعمل النوع الرابع من cout بنفس الطريقة، فهو يقوم بتعيين كائن من النوع الدائري إلى مرجع نوع النقطة C++، كما يقوم بتنفيذ ربط ثابت ويخرج أيضًا 0.
من الواضح أن هذه ليست النتيجة التي نتوقعها. في الواقع، بالنسبة للمؤشرات والمراجع، نفضل تنفيذ أساليب الكائنات الفعلية، بدلاً من تحديد أنواع المؤشرات والمراجع بشكل أعمى. هذه هي المشكلة إذا تمت كتابتها بهذه الطريقة.
إذا كنت ترغب في تلبية متطلباتنا، بغض النظر عن نوع المؤشر أو المرجع، فيجب تحديد ذلك بمرونة بناءً على الكائن الفعلي المشار إليه. ثم نحتاج إلى تغيير طريقة الربط الثابتة الافتراضية هذه واستخدام الربط الديناميكي، أي أن يتم تحديده بمرونة في وقت التشغيل.
في القسم التالي، سيتم شرح الوظائف الافتراضية بالتفصيل للجميع!