تعدد الأشكال مقابل الميراث: الفرق بين تعدد الأشكال والوراثة [2022]

نشرت: 2021-01-05

تعدد الأشكال والوراثة كلاهما مفهومان أساسيان للغاية في البرمجة الشيئية. أحدثت إضافة العناصر في لغات البرمجة الحديثة فرقًا كبيرًا في طريقة استخدامنا للغة والأشياء التي يمكننا فعلها بها. باختصار ، البرمجة الشيئية هي مجموعة من الطرق التي تسمح للمبرمج باستخدام الفئات ، وبالتالي اشتقاق كائنات بناءً على هذه الفئات.

تهدف إلى تشابه كيانات العالم الحقيقي وتسهيل على المبرمجين جعل الكود الخاص بهم شاملاً للنموذج الذي يكتبون فيه الكود. هناك أربعة مفاهيم برمجة موجهة للكائنات ، وهي الوراثة ، والتجريد ، وتعدد الأشكال ، والتغليف. الآن ، يمكن اعتبار كل فكرة ، كما ذكرنا سابقًا ، على أنها الركائز التي تقوم عليها أي لغة حديثة.

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

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

احصل على شهادات في هندسة البرمجيات من أفضل الجامعات في العالم. اربح برامج PG التنفيذية أو برامج الشهادات المتقدمة أو برامج الماجستير لتتبع حياتك المهنية بشكل سريع.

جدول المحتويات

ميراث

سيكون من الجرائم في نموذج البرمجة عدم اعتبار الوراثة مفهوم OOP بالغ الأهمية. لا ينبغي أبدًا التعامل مع أهمية الميراث باستخفاف لأن الهدف من الميراث هو "إعادة الاستخدام". ما يفعله الميراث ، كما يوحي الاسم ، هو أنه يسمح بتوسيع الشفرة المكتوبة في فئة ما إلى فئة أخرى. لذلك ، في الميراث ، توجد فئة أساسية ؛ يجب إعادة استخدام الفئة التي تمت كتابة الكود فيها.

يجب أن يتم توريث الفئة التالية التي سننشئها من هذه الفئة الأساسية لاستخدام جميع الوظائف والمتغيرات المرتبطة بالفئة الأساسية. عندما تأخذ فئة ما خصائص فئة أخرى (أو ترث من فئة مختلفة) ، يصبح جميع الأعضاء الموجودين في الفئة الأساسية عضوًا في هذه الفئة المشتقة الجديدة.

يوضح لك نموذج الكود أدناه الشكل العام للوراثة. أحد الأشياء الرئيسية التي يجب ملاحظتها هنا هو أن البنية الدقيقة التي يجب عليك كتابتها لتمكين وراثة الكود الخاص بك ستعتمد فقط على لغة البرمجة التي تختارها.

  1. اسم الفئة المشتقة من الفئة: اسم فئة الأساس access-specifier {
  2. // جسم الفئة المشتقة
  3. }

في المثال الموضح أعلاه ، تحتاج بعض الأشياء إلى شرح بسيط. كلمة "محدد الوصول" تعني الطريقة التي يمكن للفئة المشتقة من خلالها الوصول إلى خصائص وطرق الفئة الأساسية. هناك ثلاثة محددات وصول بشكل عام ، لكل منها معناها الخاص (أي خاص ، عام ، ومحمي) وممتلكات.

مرة أخرى ، بناءً على اللغة التي تختارها ، قد تضطر أو لا تضطر إلى استخدام محددات الوصول هذه. لذلك ، في عالم C ++ ، إذا ورثت دون تحديد أي شيء افتراضيًا ، فسيصبح خاصًا. ومع ذلك ، إذا ورثت من بنية (تذهب من خلال بنية الكلمة الأساسية) ، فسيكون محدد الوصول الافتراضي عامًا بدلاً من خاص.

قراءة: الفرص الوظيفية في لغة البرمجة R

يمنحك C ++ أيضًا الكثير من الخيارات للاختيار من بينها عندما تقوم بالوراثة. ستجد بعضها مدرجًا أدناه:

أ. الميراث الهرمي: يتبع هذا النوع من الميراث القاعدة التي تنص على أنه يجب أن يكون هناك فئة عليا واحدة فقط ، ومن تلك الطبقة العليا ، يجب أن يكون هناك العديد من الفئات الفرعية المشتقة. ستجد مثالاً على ذلك أدناه:

  1. // الفئة الأساسية
  2. فئة أ
  3. {
  4. متعة الفراغ العام
  5. {
  6. //
  7. }
  8. }
  9. //فئة مشتقة
  10. فئة ب: أ
  11. {
  12. متعة الفراغ العام ()
  13. {
  14. //
  15. }
  16. }
  17. //فئة مشتقة
  18. فئة ج: أ
  19. {
  20. وظيفة الفراغ العام
  21. {
  22. //
  23. }
  24. }
  25. //فئة مشتقة
  26. فئة د: ج
  27. {
  28. متعة الفراغ العام ()
  29. {
  30. //
  31. }
  32. }
  33. //فئة مشتقة
  34. فئة E: C.
  35. {
  36. متعة الفراغ العام ()
  37. {
  38. //
  39. }
  40. }
  41. //فئة مشتقة
  42. فئة F: ب
  43. {
  44. متعة الفراغ العام F ()
  45. {
  46. //
  47. }
  48. }
  49. //فئة مشتقة
  50. فئة G: ب
  51. {
  52. متعة الفراغ العام ()
  53. {
  54. //
  55. }
  56. }

ب. الوراثة المتعددة: إذا كنت تقوم بميراث متعدد ، فهذا يعني أن لديك فئة فرعية مشتقة واحدة ترث من عدة طبقات فائقة. ستجد مثالًا بسيطًا على الميراث المتعدد أدناه:

  1. // الفئة الأساسية
  2. فئة أ
  3. {
  4. متعة الفراغ العام
  5. {
  6. //
  7. }
  8. }
  9. // الفئة الأساسية
  10. الصف ب
  11. {
  12. متعة الفراغ العام ()
  13. {
  14. //
  15. }
  16. }
  17. //فئة مشتقة
  18. فئة ج: أ ، ب
  19. {
  20. وظيفة الفراغ العام
  21. {
  22. //
  23. }
  24. }

ج. الميراث الفردي: ربما يكون هذا هو أبسط أشكال الميراث. هناك فئة أساسية واحدة وفئة مشتقة واحدة. ستجد مثالاً أدناه:

  1. // الفئة الأساسية
  2. فئة أ
  3. {
  4. متعة الفراغ العام
  5. {
  6. //لكى يفعل:
  7. }
  8. }
  9. //فئة مشتقة
  10. فئة ب: أ
  11. {
  12. متعة الفراغ العام ()
  13. {
  14. //لكى يفعل:
  15. }
  16. }

تعدد الأشكال

التعريف الأساسي لكلمة تعدد الأشكال يعني وجود العديد من الأشكال. هذا التعريف يحمل بدقة شديدة في شرح تعدد الأشكال في سياق البرمجة. في هذا النموذج ، يأخذ تعدد الأشكال معنى وظيفة واحدة ولكن أشكالًا عديدة. يحدث تعدد الأشكال في الواقع في وقت الترجمة. تعدد الأشكال في وقت الترجمة ممكن فقط بسبب مفهوم التحميل الزائد ، وفي وقت التشغيل ، تجعل ميزة التجاوز تعدد الأشكال حقيقة واقعة. واحدًا تلو الآخر ، دعونا نتعامل مع تعريف كل من التحميل الزائد والتجاوز.

يتطلب التحميل الزائد كتابة الكود الذي تكتبه أو كتابة وظيفة الفصل أكثر من مرة بمعلمات مختلفة ولكن لها نفس نوع الإرجاع. هذا يعني أن الوسيطات التي تقوم بتمريرها إلى الوظيفة يمكن أن تكون مختلفة ، وفقط بالنظر إلى القيم النهائية التي يتم تمريرها إلى الوظيفة في وقت التشغيل ، يتم تحديد شكل الوظيفة التي سيتم استدعاؤها. بشكل عام ، نرى أن مُنشئ الصنف هو الوظيفة الأكثر تحميلًا. ستصبح كل هذه النظرية واضحة جدًا ، وسيكون من الأسهل عليك إدخالها في ذهنك بمساعدة مثال.

  1. فئة الزائد {
  2. الباحث أ ، ب ؛
  3. عامة:
  4. int overload (int x) {// first overload () constructor
  5. أ = س ؛
  6. عودة
  7. }
  8. int overload (int x، int y) {// second overload () constructor
  9. أ = س ؛
  10. ب = ص ؛
  11. العودة أ * ب ؛
  12. }
  13. } ؛
  14. int main () {
  15. الزائد O1 ؛
  16. O1. الزائد (20) ؛ // أول استدعاء منشئ overload ()
  17. O1. الزائد (20،40) ؛ // الثانية overload () استدعاء المُنشئ

هنا في هذا المثال ، نرى التحميل الزائد قيد التنفيذ. انظر إلى كيفية استدعاء المنشئات المختلفة اعتمادًا على ما إذا كانت القيمة النهائية لأقواس الكائن هي إما عدد صحيح واحد أو اثنان.

دعونا نتناول تعريف التجاوز بعد ذلك. يمكنك فقط تجاوز تلك الوظائف المحددة الموروثة. نعم ، الوراثة هي نقطة أساسية في جعل تجاوز الوظائف أمرًا ممكنًا. إذا كنت ترغب في كتابة دالة وتجاوزها أيضًا ، فسيتعين عليك في C ++ استخدام الكلمة الأساسية الظاهرية قبل تعريف الوظيفة ، وفي الفئة المشتقة باستخدام نفس الاسم لوظيفتك ، ما عليك سوى إزالة الكلمة الأساسية الافتراضية. لترسيخ فهمك ، إليك مثال:

  1. قاعدة الطبقة {
  2. عامة:
  3. Virtual void funct () {// الوظيفة الافتراضية للفئة الأساسية
  4. cout << "هذه وظيفة فئة أساسية ()"؛
  5. }
  6. } ؛
  7. فئة مشتقة 1: قاعدة عامة {
  8. عامة:
  9. void funct () {// أعيد تعريف الوظيفة الافتراضية للفئة الأساسية في الفئة المشتقة 1
  10. cout << "هذه وظيفة فئة مشتقة 1 ()" ؛
  11. }
  12. } ؛
  13. int main ()
  14. {
  15. قاعدة * ص ، ب ؛
  16. مشتق 1 د 1 ؛
  17. * ع = & ب ؛
  18. p-> funct () ؛ // استدعاء وظيفة الفئة الأساسية ().
  19. * ف = & د 1 ؛
  20. العودة 0 ؛
  21. }

انظر إلى كيفية استخدام الكلمة الأساسية الظاهرية في الفئة الأساسية ، وفي الفئة المشتقة ، يكون تعريف الوظيفة نفسه موجودًا فقط الكلمة الأساسية الظاهرية غائبة.

بعض الاختلافات الشائكة بين تعدد الأشكال والوراثة:

  1. الميراث هو في الأساس تكوين فصل دراسي ، ومن ثم الحصول على فصول أخرى في برنامجك تحصل على ميزاتها من الفئة الأساسية الموجودة بالفعل. ومع ذلك ، فإن تعدد الأشكال هو واجهة ، وبسبب كونها واجهة ، يمكن أن تتخذ أشكالًا وأشكالًا مختلفة.
  2. الوراثة هي خاصية تتعلق بالفئات فقط في حين أن تعدد الأشكال يمتد إلى أي طريقة و / أو وظيفة.
  3. يسمح الوراثة للفئة المشتقة باستخدام جميع الوظائف والمتغيرات المعلنة في الفئة الأساسية دون تحديدها صراحة مرة أخرى. هذا هو السبب في أننا نقول إن الوراثة تزيد من قابلية إعادة استخدام الشفرة وتقلل من طول الكود ، والذي سيتعين علينا كتابته إذا كان الميراث غائبًا. في حين أن تعدد الأشكال يسمح لنفس اسم الوظيفة بأن يكون له رمزان مختلفان تمامًا. لذا ، بمعنى ما ، بدلاً من تقليل طول الشفرة التي سنضطر إلى كتابتها ، فإن تعدد الأشكال يوسعها أكثر.
  4. هناك العديد من الأشكال التي يمكن أن تتخذها الميراث ؛ يمكنك أن تكون مبدعًا حقًا في الميراث. ومع ذلك ، لا يمكن تحقيق تعدد الأشكال إلا من خلال وسيلتين ، أي التحميل الزائد والتجاوز. لا يزال بإمكانك أن تصاب بالجنون أثناء استخدام تعدد الأشكال ، لكنك مقيد بطريقتين فقط لتطبيقه في كود الكتابة الخاص بك.

يجب أن تقرأ: يجب قراءة 47 أسئلة وأجوبة مقابلة OOPS للطلاب الجدد وذوي الخبرة

تعدد الأشكال مقابل الميراث: التمايز الجدولي

في الجدول أدناه ، ستجد فرقًا واضحًا بين تعدد الأشكال والوراثة:

إجراءات المقارنة ميراث تعدد الأشكال
الاختلافات الجوهرية بين الاثنين معنى الوراثة هو إنشاء فئات جديدة لها خصائص (وظائف ومتغيرات الفئات الموجودة) إنها في الأساس منصة تسمح لكتابة الكود بأشكال مختلفة.
يمكن دمج الاختلافات في طريقة دمج كل منهما في التعليمات البرمجية الخاصة بك يمكن للفئات فقط التمتع بالميراث الحقيقي في الكود. يمكن تنفيذه واستخدامه بواسطة أي وظائف و / أو طرق في جميع أنحاء الكود بأكمله.
الاختلافات في طريقة استخدام كل منهما. إنه يمكّن الكود الذي تمت كتابته من إعادة استخدامه داخل نفس البرنامج أو برنامج مختلف. بدونها ، ستفتقد البرمجة الموجهة للكائنات ميزة مهمة. يسمح للكائن المُعلن باتخاذ القرار بشأن شكل الوظيفة التي سيتم استدعاءها. هناك وقتان يمكن فيهما تحديد ذلك. في وقت التشغيل ، يطلق عليه تجاوز ؛ في وقت الترجمة ، يطلق عليه التحميل الزائد.
أشكال مختلفة يمكن أن يتخذها كلاهما هناك عدد كبير من الأشكال التي يمكن أن تتخذها الميراث. يمكن أن يكون هناك نوعان فقط من تعدد الأشكال. اعتمادًا على الوقت في البرنامج ، يتغير من التحميل الزائد إلى التجاوز.
مثال أساسي يوضح كيفية تنفيذ كل منها. يمكن أن ترث الدراجة الصفية من فئة المركبات ذات العجلتين ، والتي بدورها يمكن أن تكون فئة فرعية من المركبات. يمكن أن تحتوي دراجة الفصل على طريقة تسمى set_color () ، والتي تغير لون الدراجة بناءً على اسم اللون الذي أدخلته.

تحقق من: ما هو نوع Casting في Java | فهم نوع الصب كمبتدئ

خاتمة

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

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

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

إذا كنت مهتمًا بمعرفة المزيد حول تطوير البرامج كاملة المكدس ، فراجع دبلومة PG upGrad & IIIT-B في تطوير البرامج الكاملة التي تم تصميمها للمهنيين العاملين وتقدم أكثر من 500 ساعة من التدريب الصارم ، وأكثر من 9 مشاريع ، و المهام ، وحالة خريجي IIIT-B ، ومشاريع التخرج العملية العملية والمساعدة في العمل مع الشركات الكبرى.

خطط لوظيفتك في تطوير البرمجيات الآن.

تقدم بطلب للحصول على شهادة PG المرتبطة بالوظيفة من upGrad في هندسة البرمجيات