البرمجة الموجهة للكائن Object-Oriented Programming
2 مشترك
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: البرمجة بلغة ++C مع ++Microsoft Visual C
صفحة 1 من اصل 1
البرمجة الموجهة للكائن Object-Oriented Programming
البرمجة الموجهة للكائن Object-Oriented Programming
الدرس الأول :
مقدمة :
لغة C++ هي لغة كمبيوتر تدعم البرمجة الموجهة للكائنات (OOP). لماذا نحتاج إلى OOP؟ ما الذي تفعله و اللغات التقليدية مثل C و Pascal و BASIC لا تفعله ؟ ما هي المبادئ وراء OOP ؟ المفهومان الأساسيان في OOP هي الكائنات objects والفئات classes. ماذا تعني هذه المصطلحات ؟
يستكشف هذا الدرس هذه الأسئلة ويوفر نظرة عامة على الميزات التي سيتم مناقشتها . ما نقوله هنا سيكون بالضرورة عامًا إلى حد ما ، سيتم التركيز على المفاهيم التي نذكرها هنا حيث نوضحها بالتفصيل في الدروس اللاحقة.
أولا : لماذا نحتاج إلى البرمجة الموجهة للكائن ؟ OPP
تم تطوير (إكتشاف) البرمجة الموجهة للكائنات لأنه تم اكتشاف قيود limitations في الأساليب السابقة للبرمجة. لتقدير ما تفعله OOP ، نحتاج إلى فهم ماهية هذه القيود وكيف نشأت من لغات البرمجة التقليدية.
1- اللغات الإجرائية Procedural Languages
اللغات C و Pascal و FORTRAN واللغات المماثلة هي لغات إجرائية procedural languages . أي أن كل عبارة statement في اللغة تخبر الكمبيوتر بأن يفعل شيئًا : احصل على بعض المدخلات ، أضف هذه الأرقام ، قسّم على ستة ، وأعرض ذلك الإخراج . البرنامج بلغة إجرائية هو قائمة من التعليمات instructions .
بالنسبة إلى البرامج الصغيرة جدًا ، لا يلزم وجود مبدأ تنظيمي آخر (يُطلق عليه غالبًا نموذجًا paradigm ).
يقوم المبرمج بإنشاء قائمة التعليمات ، ويقوم الكمبيوتر بتنفيذها.
أ- التقسيم إلى دوال Division into Functions
عندما تصبح البرامج أكبر ، تصبح قائمة واحدة من التعليمات instructions غير عملية. قليل من المبرمجين يمكنهم فهم برنامج يتكون من أكثر من بضع مئات من العبارات ما لم يتم تقسيمها إلى وحدات أصغر. لهذا السبب ، تم اعتماد الدالة functions كوسيلة لجعل البرامج أكثر فهما لمبدعيها من البشر. (يتم استخدام مصطلح الدالة في C++ و C. في لغات أخرى ، يمكن الإشارة إلى نفس المفهوم على أنه روتين فرعي subroutine أو برنامج فرعي subprogram أو إجراء procedure.) ينقسم البرنامج الإجرائي إلى دوال و (من الناحية المثالية على الأقل) كل دالة لها غرض محدد بوضوح وربط interface محددة بوضوح للدوال الأخرى في البرنامج.
يمكن توسيع فكرة تقسيم البرنامج إلى دوال عن طريق تجميع عدد من الدوال معًا في كيان أكبر يسمى الوحدة النمطية module (التي غالبًا ما تكون ملفًا) ، لكن المبدأ مماثل : تجميع المكونات التي تنفذ قوائم التعليمات.
يعد تقسيم البرنامج إلى دوال ووحدات نمطية أحد الركائز الأساسية للبرمجة المهيكلة ، وهو مجال محدد إلى حد ما والذي أثر على تنظيم البرمجة لعدة عقود قبل ظهور البرمجة الموجهة للكائنات.
ب- مشاكل البرمجة المهيكلة Problems with Structured Programming
نظرًا لأن البرامج تنمو بشكل أكبر وأكثر تعقيدًا ، فحتى طريقة البرمجة المنظمة (المهيكلة) تبدأ في إظهار علامات القصور .يكشف تحليل أسباب ذلك عن وجود نقاط ضعف في النموذج الإجرائي نفسه. بغض النظر عن مدى تنفيذ نهج البرمجة المنظمة ، تصبح البرامج الكبيرة معقدة للغاية.
ما هي أسباب هذه المشكلات في اللغات الإجرائية؟ هناك مشكلتان مرتبطتان. أولا ، الدوال لها وصول غير مقيد إلى البيانات العامة global data . ثانياً ، توفر الدوال والبيانات غير المرتبطة ، وهي أساس النموذج الإجرائي ، نموذجًا سيئًا للعالم الحقيقي.
دعنا ندرس هذه المشاكل في سياق برنامج "المخزون" inventory . أحد عناصر item البيانات العامة المهمة في مثل هذا البرنامج هو تجميع collection العناصر الموجودة في المخزون . الدوال المختلفة تصل إلى هذه البيانات لإدخال عنصر جديد ، وعرض عنصر ، وتعديل عنصر ، وهلم جرا.
• وصول غير مقيد Unrestricted Access
في البرنامج الإجرائى procedural program ، المكتوب بلغة C على سبيل المثال ، هناك نوعان من البيانات. البيانات المحلية Local data يتم إخفاؤها داخل الدالة ، ويتم استخدامها حصريًا بواسطة الدالة . في برنامج المخزون inventory ، قد تستخدم دالة العرض البيانات المحلية لتذكر العنصر الذي كانت تعرضه. ترتبط البيانات المحلية ارتباطًا وثيقًا بدالتها وهي آمنة من التعديل بواسطة دوال أخرى.
ومع ذلك ، عندما يتعين على دالتين أو أكثر الوصول إلى نفس البيانات - وهذا ينطبق على أهم البيانات في البرنامج - عندئذٍ يجب جعل البيانات عامة (عمومية) global ، مثل مجموعة collection عناصر items المخزون. يمكن الوصول إلى البيانات العامة بواسطة أي دالة في البرنامج . يظهر الشكل ترتيب المتغيرات المحلية والعامة في برنامج إجرائي.
الشكل يبين المتغيرات المحلية والعامة فى برنامج إجرائى
في برنامج كبير ، هناك العديد من الدوال والعديد من عناصر البيانات العامة global. تتمثل المشكلة في النموذج الإجرائي procedural paradigm في أن هذا يؤدي إلى عدد أكبر من الاتصالات المحتملة بين الدوال والبيانات ، كما هو مبين في الشكل.
الشكل يبين النموذج الإجرائى The procedural paradigm
هذا العدد الكبير من الاتصالات يسبب مشاكل بعدة طرق . أولاً ، يجعل من الصعب تصور هيكل البرنامج . ثانياً ، يجعل البرنامج من الصعب تعديله. قد يتطلب التغيير الذي يتم في عنصر بيانات عامة إعادة كتابة جميع الدوال التي تصل إلى هذا العنصر.
على سبيل المثال ، في برنامج المخزون الخاص بنا ، قد يقرر شخص ما تغيير أكواد المنتج لعناصر المخزون من 5 أرقام إلى 12 رقمًا. قد يتطلب هذا التغيير من نوع بيانات قصير short إلى نوع طويل long .
يجب الآن تعديل جميع الدوال التي تعمل على البيانات للتعامل مع long بدلاً من short . إنه مشابه لما يحدث عندما ينقل السوبر ماركت المحلي الخبز من الجناح 4 إلى الجناح 7. يجب على كل من يتعامل مع السوبر ماركت معرفة أين ذهب الخبز وتعديل عادات التسوق وفقًا لذلك.
عندما يتم تعديل عناصر البيانات في برنامج كبير ، قد لا يكون من السهل تحديد الدوال التي تصل إلى البيانات ، وحتى عندما تحدد ذلك ، فإن التعديلات على الدوال قد تتسبب في عملها بشكل غير صحيح مع عناصر البيانات العامة الأخرى . كل شيء مرتبط بكل شيء آخر ، لذلك فإن التعديل في أي مكان له عواقب بعيدة المدى ، وغالبًا غير مقصودة.
• نمذجة (قولبة) العالم الحقيقي Real-World Modeling
المشكلة الثانية - والأهم من ذلك - في النموذج الإجرائي procedural paradigm هي أن ترتيبه لبيانات ودوال منفصلة يؤدي وظيفة سيئة في نمذجة الأشياء في العالم الواقعي. في العالم المادي نتعامل مع أشياء مثل الأشخاص والسيارات. هذه الكائنات لا تشبه البيانات ولا تشبه الدوال . كائنات العالم الواقعي المعقدة لها سمات (خصائص) attributes وسلوك (تصرفات – أفعال) behavior .
أ- السمات Attributes
أمثلة للسمات (تسمى أحيانًا الخصائص characteristics ) ، بالنسبة للأشخاص people ، لون العين والمسمى الوظيفي ؛ و للسيارات ، الأحصنة horsepower وعدد الأبواب. كما تبين ، فإن السمات Attributes في العالم الحقيقي تعادل البيانات data الموجودة في البرنامج : فهي تحتوي على قيم محددة معينة ، مثل الأزرق (للون العين) أو أربعة (لعدد الأبواب).
ب- السلوك Behavior
السلوك هو شيء يقوم به الكائن الواقعي استجابةً لبعض التحفيزات stimulus . إذا سألت رئيسك عن زيادة ، فسوف يقول نعم أو لا. إذا قمت بتطبيق الفرامل في السيارة ، فستتوقف عمومًا. قول شيء ما والتوقف هما مثالان على السلوك behavior.
يشبه السلوك الدالة function : فأنت تقوم باستدعاء دالة للقيام بشيء ما (عرض المخزون ، على سبيل المثال) وتقوم بذلك.
لذلك لا البيانات data ولا الدوال functions ، في حد ذاتها ، نموذج model الأشياء في العالم الحقيقي على نحو فعال.
2- نهج "توجه الكائن" The Object-Oriented Approach
الفكرة الأساسية وراء اللغات الموجهة للكائنات هي الجمع في وحدة واحدة كل من البيانات data والدوال functions التي تعمل على تلك البيانات. وتسمى هذه الوحدة كائن object .
عادة ما توفر دوال الكائن ، والتي تسمى "دوال العضو" member functions في لغة C++ ، الطريقة الوحيدة للوصول إلى بياناته. إذا كنت ترغب في قراءة عنصر بيانات في كائن ما ، يمكنك استدعاء الدالة العضو في الكائن . ستصل إلى البيانات وتعيد القيمة إليك. لا يمكنك الوصول إلى البيانات مباشرة.
البيانات تكون مخفية hidden ، لذا فهي آمنة من أي تغيير عرضي. يقال إن البيانات ودوالها تكون "مغلفة" encapsulated في كيان واحد. يعد تغليف البيانات Data encapsulation وإخفاء البيانات data hiding مصطلحين أساسيين في وصف اللغات الموجهة للكائنات.
إذا كنت ترغب في تعديل البيانات في كائن ما ، فأنت تعرف بالضبط ما هي الدوال التي تتفاعل معه : "الدوال العضو" للكائن. لا توجد دوال أخرى يمكنها الوصول إلى البيانات. هذا يبسط الكتابة وتصحيح الأخطاء والحفاظ على البرنامج .
يتكون برنامج C++ عادةً من عدد من الكائنات ، التي تتواصل communicate مع بعضها البعض عن طريق استدعاء الدوال الأعضاء لبعضهم البعض. يوضح الشكل تنظيم برنامج C++ .
الشكل يبين نموذج توجه للكائن The object-oriented paradigm.
يجب أن نذكر أن ما يسمى "دوال العضو" member functions في لغة C++ تسمى" الأساليب" methods في بعض اللغات الأخرى . ويشار إلى عناصر البيانات data items أيضًا على أنها سمات attributes أو متغيرات مثيل instance variables . يشار إلى استدعاء دالة عضو لكائن بأنه إرسال رسالة إلى الكائن sending a message . هذه المصطلحات ليست مصطلحات C++ رسمية ، ولكنها تستخدم لا سيما في تصميم "توجه الكائن" .
• تشبيه (تناظر) An Analogy
قد ترغب في التفكير في الكائنات objects كإدارات (أقسام) departments فى شركة - مثل المبيعات sales والمحاسبة accounting والموظفين personnel وما إلى ذلك . الإدارات توفر نهجا هاما لتنظيم الشركات. في معظم الشركات (باستثناء الشركات الصغيرة جدًا) ، لا يعمل الأشخاص على حل مشاكل الموظفين personnel يومًا ما ، وكشوف المرتبات payroll في اليوم التالي ، ثم يخرجون إلى الميدان field بصفتهم مندوبي مبيعات salespeople في الأسبوع التالي. كل قسم لديه موظفيه ، مع مهام محددة بوضوح . كما أن لديهم بياناتهم data الخاصة : قسم المحاسبة لديه أرقام كشوف المرتبات ، قسم المبيعات لديه أرقام مبيعات ، قسم شؤون الموظفين يحتفظ بسجلات لكل موظف ، وهلم جرا.
يتحكم الأشخاص في كل قسم ويعملون على بيانات هذا القسم . تقسيم الشركة إلى أقسام يجعل من السهل فهم أنشطة الشركة والتحكم فيها ، ويساعد في الحفاظ على سلامة المعلومات التي تستخدمها الشركة. قسم المحاسبة ، على سبيل المثال ، مسؤول عن بيانات كشوف المرتبات. إذا كنت مدير مبيعات ، وتحتاج إلى معرفة إجمالي الرواتب التي دفعت في المنطقة الجنوبية في يوليو ، فأنت لا تمشى إلى قسم المحاسبة وتبدأ في البحث في خزانات الملفات. يمكنك إرسال مذكرة إلى الشخص المناسب في القسم ، ثم انتظر وصول ذلك الشخص إلى البيانات ويرسل لك ردًا بالمعلومات التي تريدها. هذا يضمن أن يتم الوصول إلى البيانات بدقة وعدم تلفها من قبل الغرباء غير الأكفاء . يظهر الشكل تنظيم الشركات . بالطريقة نفسها ، توفر الكائنات طريقة لتنظيم البرنامج مع المساعدة في الحفاظ على سلامة بيانات البرنامج.
الشكل يبين نموذج الشركات.
• البرمجة الموجهة للكائنات : نهج للتنظيم OOP: An Approach to Organization
ضع في اعتبارك أن البرمجة الموجهة للكائنات ليست معنية أساسًا بتفاصيل تشغيل البرنامج. بدلا من ذلك ، فإنها تتعامل مع التنظيم العام للبرنامج.
تتشابه معظم عبارات statements البرنامج الفردية في لغة C++ مع العبارات statements باللغات الإجرائية ، والكثير منها مطابق للعبارات في لغة C. في الواقع ، قد تكون دالة العضو بالكامل في برنامج لغة C++ مشابهة تمامًا لدالة إجرائية في لغة C. فهي فقط عندما تنظر في السياق الأكبر ، يمكنك تحديد ما إذا كانت عبارة أو دالة جزءًا من برنامج C إجرائي أو برنامج C++ موجه للكائن.
ثانيا : خصائص اللغات الموجه للكائنات Characteristics of Object-Oriented Languages
دعنا ندرس بإيجاز بعض العناصر الرئيسية للغات الموجهة للكائنات بشكل عام ، ولغة C++ على وجه الخصوص.
1- الكائنات Objects
عندما تتعامل مع مشكلة برمجة بلغة موجهة للكائنات ، لم تعد تسأل كيف سيتم تقسيم المشكلة إلى دوال functions ، ولكن كيف سيتم تقسيمها إلى كائنات objects. التفكير في الكائنات objects ، بدلاً من الدوال functions ، له تأثير مفيد بشكل مدهش على مدى سهولة تصميم البرامج. ينتج عن هذا التطابق الوثيق بين الكائنات في معاني البرمجة والكائنات في العالم الحقيقي .
إن التوافق بين كائنات البرمجة والكائنات الواقعية هو النتيجة السعيدة لدمج البيانات data والدوال functions : توفر الكائنات الناتجة ثورة في تصميم البرنامج. لا يوجد مثل هذا التطابق الوثيق بين بنيات البرمجة والعناصر التي يتم نمذجتها بلغة إجرائية.
2- الفئات أو الأصناف Classes
في البرمجة الموجهه للكائنات OOP نقول أن الكائنات أعضاء members في "فئات" classes . ماذا يعني هذا؟ دعونا ننظر إلى التناظر (التشابهه) . تحتوي جميع لغات الكمبيوتر تقريبًا على أنواع بيانات data types مدمجة. على سبيل المثال ، يتم تحديد نوع البيانات int ، بمعنى الأعداد الصحيحة ، مسبقًا في لغة C++. يمكنك الإعلان declare عن العديد من متغيرات من التوع int حسب حاجتك في البرنامج:
بطريقة مماثلة ، يمكنك تعريف العديد من الكائنات objects من نفس الفئة class ، كما هو مبين في الشكل . تخدم الفئة class كخطة plan أو مخطط blueprint.فهى تحدد البيانات data والدوال functions التي سيتم تضمينها في كائنات تلك الفئة. لا يؤدي تعريف الفئة إلى إنشاء أي كائنات ، تمامًا كما لا يؤدي مجرد وجود نوع البيانات int إلى إنشاء أي متغيرات.
وبالتالي فإن الفئة class هى وصف لعدد من الكائنات المتشابهة . غالبًا ما يطلق على الكائن "مثيل" “instance” من الفئة .
الشكل يبين فئة وكائناتها A class and its objects
3- الوراثة Inheritance
فكرة الفئات classes تؤدي إلى فكرة الوراثة nheritance. في حياتنا اليومية ، نستخدم مفهوم الفئات المقسمة إلى فئات فرعية. نحن نعلم أن فئة الحيوان animal class تنقسم إلى ثدييات وبرمائيات وحشرات وطيور وما إلى ذلك. تنقسم فئة السيارات vehicle class إلى سيارات وشاحنات وحافلات ودراجات نارية ، وما إلى ذلك.
المبدأ في هذا النوع من التقسيم هو أن كل فئة فرعية تشترك في الخصائص المشتركة مع الفئة التي اشتقت منها. تحتوي السيارات والشاحنات والحافلات والدراجات النارية على عجلات ومحرك ؛ هذه هي الخصائص المميزة للمركبات. بالإضافة إلى الخصائص المشتركة مع الأعضاء الآخرين في الفئة ، لكل فئة فرعية أيضًا خصائصها الخاصة : تحتوي الحافلات ، على سبيل المثال ، على مقاعد للعديد من الأشخاص ، بينما تتوفر للشاحنات مساحة لنقل الأحمال الثقيلة.
تظهر هذه الفكرة في الشكل . لاحظ فى الشكل أن الخصائص (ميزات) A و B ، والتي تعد جزءًا من الفئة الأساسية base class ، مشتركة بين جميع الفئات المشتقة ، ولكن لكل فئة مشتقة أيضًا ميزات خاصة بها.
الشكل يبين الوراثة Inheritance
بطريقة مماثلة ، يمكن أن تصبح فئة برمجة موجهة للكائنات OOP أصلًا لعدة فئات فرعية. في لغة C++ تسمى الفئة الأصلية "الفئة الأساسية" base class ؛ يمكن تعريف الفئات الأخرى التي تشترك في خصائصها ، ولكنها تضيف فئاتها أيضًا. وتسمى هذه "الفئات المشتقة" derived classes.
لا تخلط فى العلاقة بين الكائنات والفئات ، من ناحية ، والعلاقة بين الفئة الأساسية والفئات المشتقة ، من ناحية أخرى. الكائنات ، الموجودة في ذاكرة الكمبيوتر ، تجسد كل منها الخصائص الدقيقة لفئتها ، والتي تعمل كقالب. ترث الفئات المشتقة بعض الخصائص من الفئة الأساسية الخاصة بها ، ولكن ممكن إضافة خصائص جديدة خاصة بها.
الوراثة تشبه إلى حد ما استخدام الدوال لتبسيط برنامج إجرائي تقليدي.
إذا وجدنا أن ثلاثة أقسام مختلفة من البرنامج الإجرائي تقوم بنفس الشيء تقريبًا ، فإننا ندرك فرصة لاستخراج العناصر المشتركة لهذه الأقسام الثلاثة ووضعها في دالة واحدة. يمكن أن تستدعي الأقسام الثلاثة للبرنامج الدالة لتنفيذ الإجراءات الشائعة ، ويمكنها أيضًا تنفيذ المعالجة الفردية الخاصة بها. وبالمثل ، تحتوي الفئة الأساسية على عناصر مشتركة في مجموعة من الفئات المشتقة. كما تفعل الدوال في برنامج إجرائي ، يقصر الميراث برنامجًا موجهًا للكائنات ويوضح العلاقة بين عناصر البرنامج.
4- إعادة الاستخدام Reusability
بمجرد كتابة الفئة وإنشاءها وتصحيحها ، يمكن توزيعها على مبرمجين آخرين لاستخدامها في برامجهم الخاصة. وهذا ما يسمى إعادة الاستخدام reusability. إنه مشابه للطريقة التي يمكن بها دمج مكتبة الدوال في لغة إجرائية في برامج مختلفة.
ومع ذلك ، فى البرمجة الموجهة للكائنات OOP ، يوفر مفهوم الوراثة inheritance امتدادًا مهمًا لفكرة إعادة الاستخدام reusability . يمكن للمبرمج أن يأخذ فئة موجودة ، ودون تعديلها ، يمكن إضافة ميزات وقدرات إضافية إليها. يتم ذلك عن طريق اشتقاق فئة جديدة من الفئة الحالية. سوف ترث الفئة الجديدة قدرات الفئة القديمة ، ولكنها حرة في إضافة ميزات جديدة خاصة بها.
على سبيل المثال ، ربما تكون قد كتبت (أو اشتريت من شخص آخر) فئة تنشئ نظام قائمة menu system، مثل ذلك المستخدم في Windows أو واجهات المستخدم الرسومية (GUIs) الأخرى. تعمل هذه الفئة بشكل جيد ، ولا ترغب في تغييرها ، ولكنك ترغب في إضافة القدرة على تشغيل وإيقاف بعض إدخالات القائمة. للقيام بذلك ، يمكنك ببساطة إنشاء فئة جديدة ترث جميع إمكانيات الفئة الحالية ولكن نضيف إدخالات القائمة الوامضة.
تعد السهولة التي يمكن بها إعادة استخدام البرامج الحالية من الفوائد المهمة للبرمجة الموجهة للكائن OOP. تجد العديد من الشركات أن القدرة على إعادة استخدام الفئات في مشروع ثان يوفر عائدًا متزايدًا على استثمارها الأصلي في البرمجة. سيكون لدينا المزيد لنقوله حول هذا الموضوع لاحقا .
5- إنشاء أنواع بيانات جديدة Creating New Data Types
أحد فوائد الكائنات هي أنها تعطي المبرمج طريقة ملائمة لإنشاء أنواع بيانات جديدة . افترض أنك تعمل بمواقع ثنائية الأبعاد (مثل إحداثيات x و y ، أو خطوط الطول والعرض) في البرنامج. تريد التعبير عن العمليات على هذه القيم الموضعية بعمليات حسابية عادية ، مثل
position1 = position2 + origin
حيث تمثل كل من المتغيرات position1 و position2 و origin زوجًا pair من الكميات العددية المستقلة. من خلال إنشاء فئة تتضمن هاتين القيمتين ، وإعلان position1 ، و position2 ، و origin ككائنات لهذه الفئة ، يمكننا ، في الواقع ، إنشاء نوع بيانات جديد. تهدف العديد من ميزات C++ إلى تسهيل إنشاء أنواع بيانات جديدة بهذه الطريقة.
6- تعدد الأشكال والتحميل الزائد Polymorphism and Overloading
لاحظ أن العوامل = (equal) و + (plus) ، المستخدمة في حساب الموضع الموضح أعلاه ، لا تتصرف بنفس الطريقة التي تعمل بها في العمليات على أنواع مدمجة مثل int. الكائنات position1 وما إلى ذلك ليست معرّفة مسبقًا في C++ ، ولكنها كائنات محددة من قبل مبرمج للفئة Position . كيف أن العوامل = و + تعرف كيفية العمل على الكائنات؟ الجواب هو أنه يمكننا تعريف سلوكيات جديدة لهذه العوامل . ستكون هذه العمليات دوال أعضاء في الفئة Position .
يسمى استخدام العوامل أو الدوال بطرق مختلفة ، اعتمادًا على ما تعمل عليه ، تعدد الأشكال polymorphism (شيء واحد مع عدة أشكال مميزة). عندما يُمنح العامل الموجود ، مثل + أو = ، القدرة على العمل على نوع بيانات جديد ، يُقال إنه محمّل بشكل زائد overloaded .
التحميل الزائد هو نوع من تعدد الأشكال. بل هو أيضا سمة مهمة للبرمجة الموجهة للكائنات OOP.
الدرس الأول :
مقدمة :
لغة C++ هي لغة كمبيوتر تدعم البرمجة الموجهة للكائنات (OOP). لماذا نحتاج إلى OOP؟ ما الذي تفعله و اللغات التقليدية مثل C و Pascal و BASIC لا تفعله ؟ ما هي المبادئ وراء OOP ؟ المفهومان الأساسيان في OOP هي الكائنات objects والفئات classes. ماذا تعني هذه المصطلحات ؟
يستكشف هذا الدرس هذه الأسئلة ويوفر نظرة عامة على الميزات التي سيتم مناقشتها . ما نقوله هنا سيكون بالضرورة عامًا إلى حد ما ، سيتم التركيز على المفاهيم التي نذكرها هنا حيث نوضحها بالتفصيل في الدروس اللاحقة.
أولا : لماذا نحتاج إلى البرمجة الموجهة للكائن ؟ OPP
تم تطوير (إكتشاف) البرمجة الموجهة للكائنات لأنه تم اكتشاف قيود limitations في الأساليب السابقة للبرمجة. لتقدير ما تفعله OOP ، نحتاج إلى فهم ماهية هذه القيود وكيف نشأت من لغات البرمجة التقليدية.
1- اللغات الإجرائية Procedural Languages
اللغات C و Pascal و FORTRAN واللغات المماثلة هي لغات إجرائية procedural languages . أي أن كل عبارة statement في اللغة تخبر الكمبيوتر بأن يفعل شيئًا : احصل على بعض المدخلات ، أضف هذه الأرقام ، قسّم على ستة ، وأعرض ذلك الإخراج . البرنامج بلغة إجرائية هو قائمة من التعليمات instructions .
بالنسبة إلى البرامج الصغيرة جدًا ، لا يلزم وجود مبدأ تنظيمي آخر (يُطلق عليه غالبًا نموذجًا paradigm ).
يقوم المبرمج بإنشاء قائمة التعليمات ، ويقوم الكمبيوتر بتنفيذها.
أ- التقسيم إلى دوال Division into Functions
عندما تصبح البرامج أكبر ، تصبح قائمة واحدة من التعليمات instructions غير عملية. قليل من المبرمجين يمكنهم فهم برنامج يتكون من أكثر من بضع مئات من العبارات ما لم يتم تقسيمها إلى وحدات أصغر. لهذا السبب ، تم اعتماد الدالة functions كوسيلة لجعل البرامج أكثر فهما لمبدعيها من البشر. (يتم استخدام مصطلح الدالة في C++ و C. في لغات أخرى ، يمكن الإشارة إلى نفس المفهوم على أنه روتين فرعي subroutine أو برنامج فرعي subprogram أو إجراء procedure.) ينقسم البرنامج الإجرائي إلى دوال و (من الناحية المثالية على الأقل) كل دالة لها غرض محدد بوضوح وربط interface محددة بوضوح للدوال الأخرى في البرنامج.
يمكن توسيع فكرة تقسيم البرنامج إلى دوال عن طريق تجميع عدد من الدوال معًا في كيان أكبر يسمى الوحدة النمطية module (التي غالبًا ما تكون ملفًا) ، لكن المبدأ مماثل : تجميع المكونات التي تنفذ قوائم التعليمات.
يعد تقسيم البرنامج إلى دوال ووحدات نمطية أحد الركائز الأساسية للبرمجة المهيكلة ، وهو مجال محدد إلى حد ما والذي أثر على تنظيم البرمجة لعدة عقود قبل ظهور البرمجة الموجهة للكائنات.
ب- مشاكل البرمجة المهيكلة Problems with Structured Programming
نظرًا لأن البرامج تنمو بشكل أكبر وأكثر تعقيدًا ، فحتى طريقة البرمجة المنظمة (المهيكلة) تبدأ في إظهار علامات القصور .يكشف تحليل أسباب ذلك عن وجود نقاط ضعف في النموذج الإجرائي نفسه. بغض النظر عن مدى تنفيذ نهج البرمجة المنظمة ، تصبح البرامج الكبيرة معقدة للغاية.
ما هي أسباب هذه المشكلات في اللغات الإجرائية؟ هناك مشكلتان مرتبطتان. أولا ، الدوال لها وصول غير مقيد إلى البيانات العامة global data . ثانياً ، توفر الدوال والبيانات غير المرتبطة ، وهي أساس النموذج الإجرائي ، نموذجًا سيئًا للعالم الحقيقي.
دعنا ندرس هذه المشاكل في سياق برنامج "المخزون" inventory . أحد عناصر item البيانات العامة المهمة في مثل هذا البرنامج هو تجميع collection العناصر الموجودة في المخزون . الدوال المختلفة تصل إلى هذه البيانات لإدخال عنصر جديد ، وعرض عنصر ، وتعديل عنصر ، وهلم جرا.
• وصول غير مقيد Unrestricted Access
في البرنامج الإجرائى procedural program ، المكتوب بلغة C على سبيل المثال ، هناك نوعان من البيانات. البيانات المحلية Local data يتم إخفاؤها داخل الدالة ، ويتم استخدامها حصريًا بواسطة الدالة . في برنامج المخزون inventory ، قد تستخدم دالة العرض البيانات المحلية لتذكر العنصر الذي كانت تعرضه. ترتبط البيانات المحلية ارتباطًا وثيقًا بدالتها وهي آمنة من التعديل بواسطة دوال أخرى.
ومع ذلك ، عندما يتعين على دالتين أو أكثر الوصول إلى نفس البيانات - وهذا ينطبق على أهم البيانات في البرنامج - عندئذٍ يجب جعل البيانات عامة (عمومية) global ، مثل مجموعة collection عناصر items المخزون. يمكن الوصول إلى البيانات العامة بواسطة أي دالة في البرنامج . يظهر الشكل ترتيب المتغيرات المحلية والعامة في برنامج إجرائي.
الشكل يبين المتغيرات المحلية والعامة فى برنامج إجرائى
في برنامج كبير ، هناك العديد من الدوال والعديد من عناصر البيانات العامة global. تتمثل المشكلة في النموذج الإجرائي procedural paradigm في أن هذا يؤدي إلى عدد أكبر من الاتصالات المحتملة بين الدوال والبيانات ، كما هو مبين في الشكل.
الشكل يبين النموذج الإجرائى The procedural paradigm
هذا العدد الكبير من الاتصالات يسبب مشاكل بعدة طرق . أولاً ، يجعل من الصعب تصور هيكل البرنامج . ثانياً ، يجعل البرنامج من الصعب تعديله. قد يتطلب التغيير الذي يتم في عنصر بيانات عامة إعادة كتابة جميع الدوال التي تصل إلى هذا العنصر.
على سبيل المثال ، في برنامج المخزون الخاص بنا ، قد يقرر شخص ما تغيير أكواد المنتج لعناصر المخزون من 5 أرقام إلى 12 رقمًا. قد يتطلب هذا التغيير من نوع بيانات قصير short إلى نوع طويل long .
يجب الآن تعديل جميع الدوال التي تعمل على البيانات للتعامل مع long بدلاً من short . إنه مشابه لما يحدث عندما ينقل السوبر ماركت المحلي الخبز من الجناح 4 إلى الجناح 7. يجب على كل من يتعامل مع السوبر ماركت معرفة أين ذهب الخبز وتعديل عادات التسوق وفقًا لذلك.
عندما يتم تعديل عناصر البيانات في برنامج كبير ، قد لا يكون من السهل تحديد الدوال التي تصل إلى البيانات ، وحتى عندما تحدد ذلك ، فإن التعديلات على الدوال قد تتسبب في عملها بشكل غير صحيح مع عناصر البيانات العامة الأخرى . كل شيء مرتبط بكل شيء آخر ، لذلك فإن التعديل في أي مكان له عواقب بعيدة المدى ، وغالبًا غير مقصودة.
• نمذجة (قولبة) العالم الحقيقي Real-World Modeling
المشكلة الثانية - والأهم من ذلك - في النموذج الإجرائي procedural paradigm هي أن ترتيبه لبيانات ودوال منفصلة يؤدي وظيفة سيئة في نمذجة الأشياء في العالم الواقعي. في العالم المادي نتعامل مع أشياء مثل الأشخاص والسيارات. هذه الكائنات لا تشبه البيانات ولا تشبه الدوال . كائنات العالم الواقعي المعقدة لها سمات (خصائص) attributes وسلوك (تصرفات – أفعال) behavior .
أ- السمات Attributes
أمثلة للسمات (تسمى أحيانًا الخصائص characteristics ) ، بالنسبة للأشخاص people ، لون العين والمسمى الوظيفي ؛ و للسيارات ، الأحصنة horsepower وعدد الأبواب. كما تبين ، فإن السمات Attributes في العالم الحقيقي تعادل البيانات data الموجودة في البرنامج : فهي تحتوي على قيم محددة معينة ، مثل الأزرق (للون العين) أو أربعة (لعدد الأبواب).
ب- السلوك Behavior
السلوك هو شيء يقوم به الكائن الواقعي استجابةً لبعض التحفيزات stimulus . إذا سألت رئيسك عن زيادة ، فسوف يقول نعم أو لا. إذا قمت بتطبيق الفرامل في السيارة ، فستتوقف عمومًا. قول شيء ما والتوقف هما مثالان على السلوك behavior.
يشبه السلوك الدالة function : فأنت تقوم باستدعاء دالة للقيام بشيء ما (عرض المخزون ، على سبيل المثال) وتقوم بذلك.
لذلك لا البيانات data ولا الدوال functions ، في حد ذاتها ، نموذج model الأشياء في العالم الحقيقي على نحو فعال.
2- نهج "توجه الكائن" The Object-Oriented Approach
الفكرة الأساسية وراء اللغات الموجهة للكائنات هي الجمع في وحدة واحدة كل من البيانات data والدوال functions التي تعمل على تلك البيانات. وتسمى هذه الوحدة كائن object .
عادة ما توفر دوال الكائن ، والتي تسمى "دوال العضو" member functions في لغة C++ ، الطريقة الوحيدة للوصول إلى بياناته. إذا كنت ترغب في قراءة عنصر بيانات في كائن ما ، يمكنك استدعاء الدالة العضو في الكائن . ستصل إلى البيانات وتعيد القيمة إليك. لا يمكنك الوصول إلى البيانات مباشرة.
البيانات تكون مخفية hidden ، لذا فهي آمنة من أي تغيير عرضي. يقال إن البيانات ودوالها تكون "مغلفة" encapsulated في كيان واحد. يعد تغليف البيانات Data encapsulation وإخفاء البيانات data hiding مصطلحين أساسيين في وصف اللغات الموجهة للكائنات.
إذا كنت ترغب في تعديل البيانات في كائن ما ، فأنت تعرف بالضبط ما هي الدوال التي تتفاعل معه : "الدوال العضو" للكائن. لا توجد دوال أخرى يمكنها الوصول إلى البيانات. هذا يبسط الكتابة وتصحيح الأخطاء والحفاظ على البرنامج .
يتكون برنامج C++ عادةً من عدد من الكائنات ، التي تتواصل communicate مع بعضها البعض عن طريق استدعاء الدوال الأعضاء لبعضهم البعض. يوضح الشكل تنظيم برنامج C++ .
الشكل يبين نموذج توجه للكائن The object-oriented paradigm.
يجب أن نذكر أن ما يسمى "دوال العضو" member functions في لغة C++ تسمى" الأساليب" methods في بعض اللغات الأخرى . ويشار إلى عناصر البيانات data items أيضًا على أنها سمات attributes أو متغيرات مثيل instance variables . يشار إلى استدعاء دالة عضو لكائن بأنه إرسال رسالة إلى الكائن sending a message . هذه المصطلحات ليست مصطلحات C++ رسمية ، ولكنها تستخدم لا سيما في تصميم "توجه الكائن" .
• تشبيه (تناظر) An Analogy
قد ترغب في التفكير في الكائنات objects كإدارات (أقسام) departments فى شركة - مثل المبيعات sales والمحاسبة accounting والموظفين personnel وما إلى ذلك . الإدارات توفر نهجا هاما لتنظيم الشركات. في معظم الشركات (باستثناء الشركات الصغيرة جدًا) ، لا يعمل الأشخاص على حل مشاكل الموظفين personnel يومًا ما ، وكشوف المرتبات payroll في اليوم التالي ، ثم يخرجون إلى الميدان field بصفتهم مندوبي مبيعات salespeople في الأسبوع التالي. كل قسم لديه موظفيه ، مع مهام محددة بوضوح . كما أن لديهم بياناتهم data الخاصة : قسم المحاسبة لديه أرقام كشوف المرتبات ، قسم المبيعات لديه أرقام مبيعات ، قسم شؤون الموظفين يحتفظ بسجلات لكل موظف ، وهلم جرا.
يتحكم الأشخاص في كل قسم ويعملون على بيانات هذا القسم . تقسيم الشركة إلى أقسام يجعل من السهل فهم أنشطة الشركة والتحكم فيها ، ويساعد في الحفاظ على سلامة المعلومات التي تستخدمها الشركة. قسم المحاسبة ، على سبيل المثال ، مسؤول عن بيانات كشوف المرتبات. إذا كنت مدير مبيعات ، وتحتاج إلى معرفة إجمالي الرواتب التي دفعت في المنطقة الجنوبية في يوليو ، فأنت لا تمشى إلى قسم المحاسبة وتبدأ في البحث في خزانات الملفات. يمكنك إرسال مذكرة إلى الشخص المناسب في القسم ، ثم انتظر وصول ذلك الشخص إلى البيانات ويرسل لك ردًا بالمعلومات التي تريدها. هذا يضمن أن يتم الوصول إلى البيانات بدقة وعدم تلفها من قبل الغرباء غير الأكفاء . يظهر الشكل تنظيم الشركات . بالطريقة نفسها ، توفر الكائنات طريقة لتنظيم البرنامج مع المساعدة في الحفاظ على سلامة بيانات البرنامج.
الشكل يبين نموذج الشركات.
• البرمجة الموجهة للكائنات : نهج للتنظيم OOP: An Approach to Organization
ضع في اعتبارك أن البرمجة الموجهة للكائنات ليست معنية أساسًا بتفاصيل تشغيل البرنامج. بدلا من ذلك ، فإنها تتعامل مع التنظيم العام للبرنامج.
تتشابه معظم عبارات statements البرنامج الفردية في لغة C++ مع العبارات statements باللغات الإجرائية ، والكثير منها مطابق للعبارات في لغة C. في الواقع ، قد تكون دالة العضو بالكامل في برنامج لغة C++ مشابهة تمامًا لدالة إجرائية في لغة C. فهي فقط عندما تنظر في السياق الأكبر ، يمكنك تحديد ما إذا كانت عبارة أو دالة جزءًا من برنامج C إجرائي أو برنامج C++ موجه للكائن.
ثانيا : خصائص اللغات الموجه للكائنات Characteristics of Object-Oriented Languages
دعنا ندرس بإيجاز بعض العناصر الرئيسية للغات الموجهة للكائنات بشكل عام ، ولغة C++ على وجه الخصوص.
1- الكائنات Objects
عندما تتعامل مع مشكلة برمجة بلغة موجهة للكائنات ، لم تعد تسأل كيف سيتم تقسيم المشكلة إلى دوال functions ، ولكن كيف سيتم تقسيمها إلى كائنات objects. التفكير في الكائنات objects ، بدلاً من الدوال functions ، له تأثير مفيد بشكل مدهش على مدى سهولة تصميم البرامج. ينتج عن هذا التطابق الوثيق بين الكائنات في معاني البرمجة والكائنات في العالم الحقيقي .
إن التوافق بين كائنات البرمجة والكائنات الواقعية هو النتيجة السعيدة لدمج البيانات data والدوال functions : توفر الكائنات الناتجة ثورة في تصميم البرنامج. لا يوجد مثل هذا التطابق الوثيق بين بنيات البرمجة والعناصر التي يتم نمذجتها بلغة إجرائية.
2- الفئات أو الأصناف Classes
في البرمجة الموجهه للكائنات OOP نقول أن الكائنات أعضاء members في "فئات" classes . ماذا يعني هذا؟ دعونا ننظر إلى التناظر (التشابهه) . تحتوي جميع لغات الكمبيوتر تقريبًا على أنواع بيانات data types مدمجة. على سبيل المثال ، يتم تحديد نوع البيانات int ، بمعنى الأعداد الصحيحة ، مسبقًا في لغة C++. يمكنك الإعلان declare عن العديد من متغيرات من التوع int حسب حاجتك في البرنامج:
- الكود:
int day;
int count;
int divisor;
int answer;
بطريقة مماثلة ، يمكنك تعريف العديد من الكائنات objects من نفس الفئة class ، كما هو مبين في الشكل . تخدم الفئة class كخطة plan أو مخطط blueprint.فهى تحدد البيانات data والدوال functions التي سيتم تضمينها في كائنات تلك الفئة. لا يؤدي تعريف الفئة إلى إنشاء أي كائنات ، تمامًا كما لا يؤدي مجرد وجود نوع البيانات int إلى إنشاء أي متغيرات.
وبالتالي فإن الفئة class هى وصف لعدد من الكائنات المتشابهة . غالبًا ما يطلق على الكائن "مثيل" “instance” من الفئة .
الشكل يبين فئة وكائناتها A class and its objects
3- الوراثة Inheritance
فكرة الفئات classes تؤدي إلى فكرة الوراثة nheritance. في حياتنا اليومية ، نستخدم مفهوم الفئات المقسمة إلى فئات فرعية. نحن نعلم أن فئة الحيوان animal class تنقسم إلى ثدييات وبرمائيات وحشرات وطيور وما إلى ذلك. تنقسم فئة السيارات vehicle class إلى سيارات وشاحنات وحافلات ودراجات نارية ، وما إلى ذلك.
المبدأ في هذا النوع من التقسيم هو أن كل فئة فرعية تشترك في الخصائص المشتركة مع الفئة التي اشتقت منها. تحتوي السيارات والشاحنات والحافلات والدراجات النارية على عجلات ومحرك ؛ هذه هي الخصائص المميزة للمركبات. بالإضافة إلى الخصائص المشتركة مع الأعضاء الآخرين في الفئة ، لكل فئة فرعية أيضًا خصائصها الخاصة : تحتوي الحافلات ، على سبيل المثال ، على مقاعد للعديد من الأشخاص ، بينما تتوفر للشاحنات مساحة لنقل الأحمال الثقيلة.
تظهر هذه الفكرة في الشكل . لاحظ فى الشكل أن الخصائص (ميزات) A و B ، والتي تعد جزءًا من الفئة الأساسية base class ، مشتركة بين جميع الفئات المشتقة ، ولكن لكل فئة مشتقة أيضًا ميزات خاصة بها.
الشكل يبين الوراثة Inheritance
بطريقة مماثلة ، يمكن أن تصبح فئة برمجة موجهة للكائنات OOP أصلًا لعدة فئات فرعية. في لغة C++ تسمى الفئة الأصلية "الفئة الأساسية" base class ؛ يمكن تعريف الفئات الأخرى التي تشترك في خصائصها ، ولكنها تضيف فئاتها أيضًا. وتسمى هذه "الفئات المشتقة" derived classes.
لا تخلط فى العلاقة بين الكائنات والفئات ، من ناحية ، والعلاقة بين الفئة الأساسية والفئات المشتقة ، من ناحية أخرى. الكائنات ، الموجودة في ذاكرة الكمبيوتر ، تجسد كل منها الخصائص الدقيقة لفئتها ، والتي تعمل كقالب. ترث الفئات المشتقة بعض الخصائص من الفئة الأساسية الخاصة بها ، ولكن ممكن إضافة خصائص جديدة خاصة بها.
الوراثة تشبه إلى حد ما استخدام الدوال لتبسيط برنامج إجرائي تقليدي.
إذا وجدنا أن ثلاثة أقسام مختلفة من البرنامج الإجرائي تقوم بنفس الشيء تقريبًا ، فإننا ندرك فرصة لاستخراج العناصر المشتركة لهذه الأقسام الثلاثة ووضعها في دالة واحدة. يمكن أن تستدعي الأقسام الثلاثة للبرنامج الدالة لتنفيذ الإجراءات الشائعة ، ويمكنها أيضًا تنفيذ المعالجة الفردية الخاصة بها. وبالمثل ، تحتوي الفئة الأساسية على عناصر مشتركة في مجموعة من الفئات المشتقة. كما تفعل الدوال في برنامج إجرائي ، يقصر الميراث برنامجًا موجهًا للكائنات ويوضح العلاقة بين عناصر البرنامج.
4- إعادة الاستخدام Reusability
بمجرد كتابة الفئة وإنشاءها وتصحيحها ، يمكن توزيعها على مبرمجين آخرين لاستخدامها في برامجهم الخاصة. وهذا ما يسمى إعادة الاستخدام reusability. إنه مشابه للطريقة التي يمكن بها دمج مكتبة الدوال في لغة إجرائية في برامج مختلفة.
ومع ذلك ، فى البرمجة الموجهة للكائنات OOP ، يوفر مفهوم الوراثة inheritance امتدادًا مهمًا لفكرة إعادة الاستخدام reusability . يمكن للمبرمج أن يأخذ فئة موجودة ، ودون تعديلها ، يمكن إضافة ميزات وقدرات إضافية إليها. يتم ذلك عن طريق اشتقاق فئة جديدة من الفئة الحالية. سوف ترث الفئة الجديدة قدرات الفئة القديمة ، ولكنها حرة في إضافة ميزات جديدة خاصة بها.
على سبيل المثال ، ربما تكون قد كتبت (أو اشتريت من شخص آخر) فئة تنشئ نظام قائمة menu system، مثل ذلك المستخدم في Windows أو واجهات المستخدم الرسومية (GUIs) الأخرى. تعمل هذه الفئة بشكل جيد ، ولا ترغب في تغييرها ، ولكنك ترغب في إضافة القدرة على تشغيل وإيقاف بعض إدخالات القائمة. للقيام بذلك ، يمكنك ببساطة إنشاء فئة جديدة ترث جميع إمكانيات الفئة الحالية ولكن نضيف إدخالات القائمة الوامضة.
تعد السهولة التي يمكن بها إعادة استخدام البرامج الحالية من الفوائد المهمة للبرمجة الموجهة للكائن OOP. تجد العديد من الشركات أن القدرة على إعادة استخدام الفئات في مشروع ثان يوفر عائدًا متزايدًا على استثمارها الأصلي في البرمجة. سيكون لدينا المزيد لنقوله حول هذا الموضوع لاحقا .
5- إنشاء أنواع بيانات جديدة Creating New Data Types
أحد فوائد الكائنات هي أنها تعطي المبرمج طريقة ملائمة لإنشاء أنواع بيانات جديدة . افترض أنك تعمل بمواقع ثنائية الأبعاد (مثل إحداثيات x و y ، أو خطوط الطول والعرض) في البرنامج. تريد التعبير عن العمليات على هذه القيم الموضعية بعمليات حسابية عادية ، مثل
position1 = position2 + origin
حيث تمثل كل من المتغيرات position1 و position2 و origin زوجًا pair من الكميات العددية المستقلة. من خلال إنشاء فئة تتضمن هاتين القيمتين ، وإعلان position1 ، و position2 ، و origin ككائنات لهذه الفئة ، يمكننا ، في الواقع ، إنشاء نوع بيانات جديد. تهدف العديد من ميزات C++ إلى تسهيل إنشاء أنواع بيانات جديدة بهذه الطريقة.
6- تعدد الأشكال والتحميل الزائد Polymorphism and Overloading
لاحظ أن العوامل = (equal) و + (plus) ، المستخدمة في حساب الموضع الموضح أعلاه ، لا تتصرف بنفس الطريقة التي تعمل بها في العمليات على أنواع مدمجة مثل int. الكائنات position1 وما إلى ذلك ليست معرّفة مسبقًا في C++ ، ولكنها كائنات محددة من قبل مبرمج للفئة Position . كيف أن العوامل = و + تعرف كيفية العمل على الكائنات؟ الجواب هو أنه يمكننا تعريف سلوكيات جديدة لهذه العوامل . ستكون هذه العمليات دوال أعضاء في الفئة Position .
يسمى استخدام العوامل أو الدوال بطرق مختلفة ، اعتمادًا على ما تعمل عليه ، تعدد الأشكال polymorphism (شيء واحد مع عدة أشكال مميزة). عندما يُمنح العامل الموجود ، مثل + أو = ، القدرة على العمل على نوع بيانات جديد ، يُقال إنه محمّل بشكل زائد overloaded .
التحميل الزائد هو نوع من تعدد الأشكال. بل هو أيضا سمة مهمة للبرمجة الموجهة للكائنات OOP.
الدرس الثانى الكائنات والفئات Objects and Classes
الدرس الثانى
الكائنات والفئات Objects and Classes
والآن ، المواضيع التي كناننتظرها جميعًا : الكائنات objects والفئات classes . لقد تعلمنا الهياكل structures ، والتي توفر وسيلة لتجميع عناصر البيانات. لقد تفحصنا الدوال functions، التي تنظم أفعال البرنامج في كيانات محددة. في هذا الدرس ، سنجمع هذه الأفكار معًا لإنشاء الفئات classes . سنقدم العديد من الفئات ، بدءًا من الفئات البسيطة والعمل على أمثلة أكثر تعقيدًا. سنركز أولاً على تفاصيل الفئات والكائنات. في نهاية الدرس ، سنتخذ وجهة نظر أوسع ، حيث نناقش ما الذي يمكن اكتسابه باستخدام نهج OOP.
أثناء قراءة هذا الدرس ، قد ترغب في الرجوع إلى المفاهيم المقدمة في الدرس الأول .
فئة بسيطة A Simple Class
يحتوي برنامجنا الأول على فئة وكائنين من هذه الفئة . على الرغم من أنه بسيط ، إلا أن البرنامج يوضح بناء الجملة والميزات العامة للفئات في C++ . فيما يلي قائمة لبرنامج SMALLOBJ:
تحتوي الفئة smallobj المعرفة في هذا البرنامج على عنصر بيانات واحد data item ودالتين عضوين member functions . توفر الدالتان العضوان الوصول الوحيد إلى عنصر البيانات من خارج الفئة . تقوم الدالة العضو الأولى بتعيين set عنصر البيانات إلى قيمة value ، وتعرض الثانية القيمة. (قد يبدو هذا مثل اللغة اليونانية ، لكننا سنرى ما تعنيه هذه المصطلحات أثناء تقدمنا).
يعد وضع البيانات data والدوال functions معًا في كيان واحد فكرة مركزية في البرمجة الموجهة للكائنات. هذا مبين في الشكل.
الشكل يبين أن الفئات تحتوي على بيانات ودوال Classes contain data and functions
• الفئات والكائنات Classes and Objects
تذكر من الدرس الأول أن الكائن object له نفس العلاقة بفئة class كعلاقة المتغير variable بنوع بيانات data type. يقال إن الكائن هو مثيل instance لفئة ، بالطريقة نفسها ، تعد سيارتي شيفروليه 1954 مثيلًا لمركبة vehicle . في SMALLOBJ ، يتم تعريف الفئة - واسمها smallobj - في الجزء الأول من البرنامج . في وقت لاحق ، في main() ، نعرف كائنين - s1 و s2 - وهما مثيلان تلك الفئة.
يتم إعطاء قيمة value لكل كائن ، ويعرض كل منهما قيمته. إليك مخرجات البرنامج:
سنبدأ النظر بالتفصيل في الجزء الأول من البرنامج - تعريف الفئة smallobj . في وقت لاحق سنركز على ما الذى تفعلة الدالة main() مع كائنات هذه الفئة.
• تعريف الفئة Defining the Class
فيما يلي التعريف (يطلق عليه أحيانًا المحدد specifier ) للفئة smallobj ، المنسوخة من قائمة SMALLOBJ:
يبدأ التعريف بالكلمة المفتاحية class ، متبوعة باسم الفئة - smallobj في هذا المثال. مثل الهيكل structure ، يتم تحديد جسم الفئة بواسطة الأقواس {} ويتم إنهاؤه بفاصلة منقوطة ( . (لا تنس الفاصلة المنقوطة. تذكر أن بناء البيانات مثل الهياكل والفئات تنتهي بفاصلة منقوطة ، في حين أن بنيات التحكم مثل الدالات والحلقات لا تنتهي بها .)
الخاصة والعامة private and public
يحتوي جسم الفئة على كلمتين مفتاحتيين غير مألوفتين: خاصة private وعامة public . ما هو الغرض منها؟
من السمات الرئيسية للبرمجة الموجهة للكائن إخفاء البيانات data hiding . هذا المصطلح يعني أن البيانات مخفية داخل الفئة بحيث لا يمكن الوصول إليها عن طريق الخطأ من خلال دوال خارج الفئة . تتمثل الآلية الأساسية لإخفاء البيانات في وضعها في الفئة وجعلها خاصة private . لا يمكن الوصول إلى البيانات أو الدوال الخاصة private إلا من داخل الفئة . البيانات أو الدوال العامة public ، من ناحية أخرى ، يمكن الوصول إليها من خارج الفئة الفصل. هذا مبين في الشكل .
الشكل يبين الخاصة والعامة Private and public
مخفي من من؟ Hidden from Whom?
لا تخلط بين إخفاء البيانات وتقنيات الأمان المستخدمة لحماية قواعد بيانات الكمبيوتر. لتوفير تدبير أمني ، على سبيل المثال ، قد تطلب من المستخدم توفير كلمة مرور قبل منح حق الوصول إلى قاعدة البيانات. تهدف كلمة المرور إلى منع المستخدمين غير المصرح لهم أو المشاغبين من تغيير البيانات (أو حتى قراءتها في كثير من الأحيان).
إخفاء البيانات ، من ناحية أخرى ، يعني إخفاء البيانات من أجزاء البرنامج التي لا تحتاج إلى الوصول إليها. وبشكل أكثر تحديدًا ، يتم إخفاء بيانات إحدى الفئات عن الفئات الأخرى. تم تصميم إخفاء البيانات لحماية المبرمجين حسني النية من الأخطاء البريئة . يمكن للمبرمجين الذين يريدون حقًا اكتشاف طريقة للوصول إلى البيانات الخاصة ، لكنهم سيجدون صعوبة في القيام بذلك عن طريق الصدفة.
بيانات الفئة Class Data
تحتوي الفئة smallobj على عنصر بيانات واحد : somedata ، وهو من النوع int. تسمى عناصر البيانات data items داخل الفئة أعضاء البيانات data members (أو في بعض الأحيان بيانات الأعضاء member data). يمكن أن يكون هناك أي عدد من أعضاء البيانات في الفئة ، تمامًا كما يمكن أن يكون هناك أي عدد من عناصر البيانات في الهيكل structure. يتبع عضو البيانات somedata الكلمة private ، لذلك يمكن الوصول إليها من داخل الفئة ، ولكن ليس من الخارج.
الدوال الأعضاء Member Functions
الدوال الأعضاء Member functions هي الدوال التي يتم تضمينها داخل الفئة class . (في بعض اللغات الموجهة للكائنات ، مثل Smalltalk ، تسمى دوال العضو الأساليب methods ؛ يستخدم بعض الكتاب هذا المصطلح في C++ أيضًا.) هناك دالتان أعضاء في الفئة smallobj : setdata() و showdata() .
تمت كتابة جسم الدالة لهذه الدوال لى نفس السطر مثل الأقواس التي تحددها. يمكنك أيضًا استخدام التنسيق الأكثر تقليدية لتعريفات الدوال هذه :
ومع ذلك ، عندما تكون دوال الأعضاء صغيرة ، فمن الشائع ضغط تعاريفها بهذه الطريقة لتوفير المساحة.
نظرًا لأن setdata() و showdata() يتبعان الكلمة المفتاحية public ، يمكن الوصول إليهما من خارج الفئة . سنرى كيف يتم ذلك بعد لحظة. يوضح الشكل بناء جملة تعريف الفئة.
الشكل يبين بناء جملة تعريف الفئة Syntax of a class definition
الدوال تكون عامة ، والبيانات تكون خاصة Functions Are Public, Data Is Private
عادة ما تكون البيانات داخل الفئة خاصة private والدوال عامة public . هذا هو نتيجة لطريقة استخدام الفئات . يتم إخفاء البيانات بحيث تكون في مأمن من المعالجة العرضية ، بينما تكون الدوال التي تعمل على البيانات عامة حتى يمكن الوصول إليها من خارج الفئة .
ومع ذلك ، لا توجد قاعدة تقول أن البيانات يجب أن تكون خاصة والدوال عامة ؛ في بعض الحالات ، قد تجد أنك ستحتاج إلى استخدام الدوال الخاصة والبيانات العامة.
الدوال الأعضاء داخل تعريف الفئة Member Functions Within Class Definition
تقوم الدوال الأعضاء في الفئة smallobj بتنفيذ عمليات شائعة جدًا في الفئات : إعداد setting البيانات المخزنة في الفئة واستردادها. تقبل الدالة setdata() قيمة value كبارامتر وتعيين set المتغير somedata على هذه القيمة. تعرض الدالة showdata() القيمة المخزّنة في المتغير somedata.
لاحظ أن الدالتين الأعضاء setdata() و showdata() هما تعريفان definitions حيث أن الكود الفعلي للدالة موجود في تعريف الفئة. (الدالات ليست تعريفات بمعنى أن الذاكرة مخصصة لكود الدالة ؛ هذا لا يحدث حتى يتم إنشاء كائن من الفئة.) يتم إنشاء دوال الأعضاء المعرفة داخل الفئة بهذه الطريقة كدوال مضمنة inline بشكل افتراضي . سنرى لاحقًا أنه من الممكن أيضًا إعلان declare دالة داخل فئة ولكن مع تعريفها definition في مكان آخر.
الدوال المعرفة خارج الفئة ليست عادة مضمنة inline .
• استخدام الفئة Using the Class
الآن بعد تعريف الفئة ، دعونا نرى كيف تستفيد main() منه. سنرى كيف يتم تعريف الكائنات ، وبمجرد تعريفها ، كيف يتم الوصول إلى الدوال الأعضاء.
تعريف الكائنات Defining Objects
العبارة الأولى في main()
تعرف الكائنين ، s1 و s2 ، من الفئة smallobj. تذكر أن تعريف الفئة smallobj لا يخلق أي كائنات. إنه يصف فقط كيفية ظهورها عند إنشائها ، تمامًا كما يصف تعريف الهيكل structure كيف سيبدو الهيكل ولكن لا ينشئ أي متغيرات هيكل . هذه الكائنات التي تشارك في عمليات البرنامج. يشبه تعريف كائن تعريف متغير من أي نوع بيانات : يتم تخصيص مساحة له في الذاكرة.
تعريف الكائنات بهذه الطريقة يعني إنشائها creating . وهذا ما يسمى أيضا إنشاء مثيل instantiating . ينشأ مصطلح إنشاء مثيل لأنه يتم إنشاء مثيل للفئة. الكائن هو مثيل (أي مثال محدد) لفئة. تسمى الكائنات أحيانًا متغيرات المثيل instance variables .
• استدعاء الدوال العضو Calling Member Functions
تستدعي العبارتان التاليتان في main() الدالة العضو setdata() :
هذه العبارات لا تشبه استدعاءات الدوال العادية. لماذا ترتبط أسماء الكائنات s1 و s2 بأسماء الوظائف بنقطة period ؟ يتم استخدام بناء الجملة الغريب هذا لاستدعاء دالة عضو مرتبطة associated with بكائن معين specific object . لأن setdata() هي دالة عضو في الفئة smallobj ، يجب دائمًا استدعاؤها مرتبطة يتعلق بكائن من هذه الفئة. ليس من المنطقي القول
لذاتها ، لأنه يتم استدعاء دالة العضو دائمًا للعمل على كائن محدد ، وليس على الفئة بشكل عام. ستكون محاولة الوصول إلى الفئة بهذه الطريقة كمحاولة قيادة مخطط blueprint السيارة. هذه العبارة ليست منطقية فحسب ، ولكن المترجم سيصدر رسالة خطأ إذا حاولت ذلك. لا يمكن الوصول إلى الدوال الأعضاء للفئة إلا عن طريق كائن من هذه الفئة.
لاستخدام دالة عضو ، يقوم عامل النقطة (.) (الفترة period ) بربط (بتوصيل) connect اسم الكائن ودالة العضو. يشبه بناء الجملة الطريقة التي نشير بها إلى أعضاء الهيكل ، لكن الأقواس تشير إلى أننا ننفذ دالة عضو بدلاً من الإشارة إلى عنصر بيانات. (يُطلق على عامل النقطة أيضًا عامل الوصول إلى عضو الفئة class member access ).
الاستدعاء الأول للدالة setdata() :
ينفذ الدالة العضو setdata() للكائن s1. تقوم هذه الدالة بتعيين (بضبط) set المتغير somedata في الكائن s1 على القيمة 1066. الاستدعاء الثانى :
يؤدي إلى تعيين المتغير somedata في الكائن s2 على القيمة 1776. الآن لدينا كائنان لهما المتغيرات somedata لها قيم مختلفة ، كما هو مبين في الشكل .
الشكل يبين كائنان من الفئة smallobj
وبالمثل ، سيؤدي الاستدعاءان التاليان للدالة showdata() إلى أن يعرض الكائنان قيمهما:
الرسائل Messages
تشير بعض اللغات الموجهة للكائنات إلى استدعاءات الدوال الأعضاء كرسائل messages . وبالتالي فإن الاستدعاء :
يمكن التفكير فيه كإرسال رسالة sending a message إلى الكائن s1 لإخباره بإظهار بياناته. مصطلح الرسالة ليس مصطلحًا رسميًا في لغة C++ ، لكن من المفيد أن نأخذه في الاعتبار عند مناقشتنا الدوال الأعضاء.
الحديث عن الرسائل يؤكد أن الكائنات كيانات منفصلة وأننا نتواصل معها من خلال استدعاء الدوال الأعضاء. بالإشارة إلى التشابه مع تنظيم الشركة في الدرس الأول ، من المفضل إرسال رسالة إلى السكرتير في قسم المبيعات لطلب قائمة بالمنتجات التي تباع في منطقة التوزيع الجنوبية الغربية.
الكائنات والفئات Objects and Classes
والآن ، المواضيع التي كناننتظرها جميعًا : الكائنات objects والفئات classes . لقد تعلمنا الهياكل structures ، والتي توفر وسيلة لتجميع عناصر البيانات. لقد تفحصنا الدوال functions، التي تنظم أفعال البرنامج في كيانات محددة. في هذا الدرس ، سنجمع هذه الأفكار معًا لإنشاء الفئات classes . سنقدم العديد من الفئات ، بدءًا من الفئات البسيطة والعمل على أمثلة أكثر تعقيدًا. سنركز أولاً على تفاصيل الفئات والكائنات. في نهاية الدرس ، سنتخذ وجهة نظر أوسع ، حيث نناقش ما الذي يمكن اكتسابه باستخدام نهج OOP.
أثناء قراءة هذا الدرس ، قد ترغب في الرجوع إلى المفاهيم المقدمة في الدرس الأول .
فئة بسيطة A Simple Class
يحتوي برنامجنا الأول على فئة وكائنين من هذه الفئة . على الرغم من أنه بسيط ، إلا أن البرنامج يوضح بناء الجملة والميزات العامة للفئات في C++ . فيما يلي قائمة لبرنامج SMALLOBJ:
- الكود:
// smallobj.cpp
// demonstrates a small, simple object
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class smallobj //define a class
{
private:
int somedata; //class data
public:
void setdata(int d) //member function to set data
{ somedata = d; }
void showdata() //member function to display data
{ cout << “Data is “ << somedata << endl; }
};
////////////////////////////////////////////////////////////////
int main()
{
smallobj s1, s2; //define two objects of class smallobj
s1.setdata(1066); //call member function to set data
s2.setdata(1776);
s1.showdata(); //call member function to display data
s2.showdata();
return 0;
}
تحتوي الفئة smallobj المعرفة في هذا البرنامج على عنصر بيانات واحد data item ودالتين عضوين member functions . توفر الدالتان العضوان الوصول الوحيد إلى عنصر البيانات من خارج الفئة . تقوم الدالة العضو الأولى بتعيين set عنصر البيانات إلى قيمة value ، وتعرض الثانية القيمة. (قد يبدو هذا مثل اللغة اليونانية ، لكننا سنرى ما تعنيه هذه المصطلحات أثناء تقدمنا).
يعد وضع البيانات data والدوال functions معًا في كيان واحد فكرة مركزية في البرمجة الموجهة للكائنات. هذا مبين في الشكل.
الشكل يبين أن الفئات تحتوي على بيانات ودوال Classes contain data and functions
• الفئات والكائنات Classes and Objects
تذكر من الدرس الأول أن الكائن object له نفس العلاقة بفئة class كعلاقة المتغير variable بنوع بيانات data type. يقال إن الكائن هو مثيل instance لفئة ، بالطريقة نفسها ، تعد سيارتي شيفروليه 1954 مثيلًا لمركبة vehicle . في SMALLOBJ ، يتم تعريف الفئة - واسمها smallobj - في الجزء الأول من البرنامج . في وقت لاحق ، في main() ، نعرف كائنين - s1 و s2 - وهما مثيلان تلك الفئة.
يتم إعطاء قيمة value لكل كائن ، ويعرض كل منهما قيمته. إليك مخرجات البرنامج:
- الكود:
Data is 1066 ← object s1 displayed this
Data is 1776 ← object s2 displayed this
سنبدأ النظر بالتفصيل في الجزء الأول من البرنامج - تعريف الفئة smallobj . في وقت لاحق سنركز على ما الذى تفعلة الدالة main() مع كائنات هذه الفئة.
• تعريف الفئة Defining the Class
فيما يلي التعريف (يطلق عليه أحيانًا المحدد specifier ) للفئة smallobj ، المنسوخة من قائمة SMALLOBJ:
- الكود:
class smallobj //define a class
{
private:
int somedata; //class data
public:
void setdata(int d) //member function to set data
{ somedata = d; }
void showdata() //member function to display data
{ cout << “\nData is “ << somedata; }
};
يبدأ التعريف بالكلمة المفتاحية class ، متبوعة باسم الفئة - smallobj في هذا المثال. مثل الهيكل structure ، يتم تحديد جسم الفئة بواسطة الأقواس {} ويتم إنهاؤه بفاصلة منقوطة ( . (لا تنس الفاصلة المنقوطة. تذكر أن بناء البيانات مثل الهياكل والفئات تنتهي بفاصلة منقوطة ، في حين أن بنيات التحكم مثل الدالات والحلقات لا تنتهي بها .)
الخاصة والعامة private and public
يحتوي جسم الفئة على كلمتين مفتاحتيين غير مألوفتين: خاصة private وعامة public . ما هو الغرض منها؟
من السمات الرئيسية للبرمجة الموجهة للكائن إخفاء البيانات data hiding . هذا المصطلح يعني أن البيانات مخفية داخل الفئة بحيث لا يمكن الوصول إليها عن طريق الخطأ من خلال دوال خارج الفئة . تتمثل الآلية الأساسية لإخفاء البيانات في وضعها في الفئة وجعلها خاصة private . لا يمكن الوصول إلى البيانات أو الدوال الخاصة private إلا من داخل الفئة . البيانات أو الدوال العامة public ، من ناحية أخرى ، يمكن الوصول إليها من خارج الفئة الفصل. هذا مبين في الشكل .
الشكل يبين الخاصة والعامة Private and public
مخفي من من؟ Hidden from Whom?
لا تخلط بين إخفاء البيانات وتقنيات الأمان المستخدمة لحماية قواعد بيانات الكمبيوتر. لتوفير تدبير أمني ، على سبيل المثال ، قد تطلب من المستخدم توفير كلمة مرور قبل منح حق الوصول إلى قاعدة البيانات. تهدف كلمة المرور إلى منع المستخدمين غير المصرح لهم أو المشاغبين من تغيير البيانات (أو حتى قراءتها في كثير من الأحيان).
إخفاء البيانات ، من ناحية أخرى ، يعني إخفاء البيانات من أجزاء البرنامج التي لا تحتاج إلى الوصول إليها. وبشكل أكثر تحديدًا ، يتم إخفاء بيانات إحدى الفئات عن الفئات الأخرى. تم تصميم إخفاء البيانات لحماية المبرمجين حسني النية من الأخطاء البريئة . يمكن للمبرمجين الذين يريدون حقًا اكتشاف طريقة للوصول إلى البيانات الخاصة ، لكنهم سيجدون صعوبة في القيام بذلك عن طريق الصدفة.
بيانات الفئة Class Data
تحتوي الفئة smallobj على عنصر بيانات واحد : somedata ، وهو من النوع int. تسمى عناصر البيانات data items داخل الفئة أعضاء البيانات data members (أو في بعض الأحيان بيانات الأعضاء member data). يمكن أن يكون هناك أي عدد من أعضاء البيانات في الفئة ، تمامًا كما يمكن أن يكون هناك أي عدد من عناصر البيانات في الهيكل structure. يتبع عضو البيانات somedata الكلمة private ، لذلك يمكن الوصول إليها من داخل الفئة ، ولكن ليس من الخارج.
الدوال الأعضاء Member Functions
الدوال الأعضاء Member functions هي الدوال التي يتم تضمينها داخل الفئة class . (في بعض اللغات الموجهة للكائنات ، مثل Smalltalk ، تسمى دوال العضو الأساليب methods ؛ يستخدم بعض الكتاب هذا المصطلح في C++ أيضًا.) هناك دالتان أعضاء في الفئة smallobj : setdata() و showdata() .
تمت كتابة جسم الدالة لهذه الدوال لى نفس السطر مثل الأقواس التي تحددها. يمكنك أيضًا استخدام التنسيق الأكثر تقليدية لتعريفات الدوال هذه :
- الكود:
void setdata(int d)
{
somedata = d;
}
void showdata()
{
cout << “\nData is “ << somedata;
}
ومع ذلك ، عندما تكون دوال الأعضاء صغيرة ، فمن الشائع ضغط تعاريفها بهذه الطريقة لتوفير المساحة.
نظرًا لأن setdata() و showdata() يتبعان الكلمة المفتاحية public ، يمكن الوصول إليهما من خارج الفئة . سنرى كيف يتم ذلك بعد لحظة. يوضح الشكل بناء جملة تعريف الفئة.
الشكل يبين بناء جملة تعريف الفئة Syntax of a class definition
الدوال تكون عامة ، والبيانات تكون خاصة Functions Are Public, Data Is Private
عادة ما تكون البيانات داخل الفئة خاصة private والدوال عامة public . هذا هو نتيجة لطريقة استخدام الفئات . يتم إخفاء البيانات بحيث تكون في مأمن من المعالجة العرضية ، بينما تكون الدوال التي تعمل على البيانات عامة حتى يمكن الوصول إليها من خارج الفئة .
ومع ذلك ، لا توجد قاعدة تقول أن البيانات يجب أن تكون خاصة والدوال عامة ؛ في بعض الحالات ، قد تجد أنك ستحتاج إلى استخدام الدوال الخاصة والبيانات العامة.
الدوال الأعضاء داخل تعريف الفئة Member Functions Within Class Definition
تقوم الدوال الأعضاء في الفئة smallobj بتنفيذ عمليات شائعة جدًا في الفئات : إعداد setting البيانات المخزنة في الفئة واستردادها. تقبل الدالة setdata() قيمة value كبارامتر وتعيين set المتغير somedata على هذه القيمة. تعرض الدالة showdata() القيمة المخزّنة في المتغير somedata.
لاحظ أن الدالتين الأعضاء setdata() و showdata() هما تعريفان definitions حيث أن الكود الفعلي للدالة موجود في تعريف الفئة. (الدالات ليست تعريفات بمعنى أن الذاكرة مخصصة لكود الدالة ؛ هذا لا يحدث حتى يتم إنشاء كائن من الفئة.) يتم إنشاء دوال الأعضاء المعرفة داخل الفئة بهذه الطريقة كدوال مضمنة inline بشكل افتراضي . سنرى لاحقًا أنه من الممكن أيضًا إعلان declare دالة داخل فئة ولكن مع تعريفها definition في مكان آخر.
الدوال المعرفة خارج الفئة ليست عادة مضمنة inline .
• استخدام الفئة Using the Class
الآن بعد تعريف الفئة ، دعونا نرى كيف تستفيد main() منه. سنرى كيف يتم تعريف الكائنات ، وبمجرد تعريفها ، كيف يتم الوصول إلى الدوال الأعضاء.
تعريف الكائنات Defining Objects
العبارة الأولى في main()
- الكود:
smallobj s1, s2;
تعرف الكائنين ، s1 و s2 ، من الفئة smallobj. تذكر أن تعريف الفئة smallobj لا يخلق أي كائنات. إنه يصف فقط كيفية ظهورها عند إنشائها ، تمامًا كما يصف تعريف الهيكل structure كيف سيبدو الهيكل ولكن لا ينشئ أي متغيرات هيكل . هذه الكائنات التي تشارك في عمليات البرنامج. يشبه تعريف كائن تعريف متغير من أي نوع بيانات : يتم تخصيص مساحة له في الذاكرة.
تعريف الكائنات بهذه الطريقة يعني إنشائها creating . وهذا ما يسمى أيضا إنشاء مثيل instantiating . ينشأ مصطلح إنشاء مثيل لأنه يتم إنشاء مثيل للفئة. الكائن هو مثيل (أي مثال محدد) لفئة. تسمى الكائنات أحيانًا متغيرات المثيل instance variables .
• استدعاء الدوال العضو Calling Member Functions
تستدعي العبارتان التاليتان في main() الدالة العضو setdata() :
- الكود:
s1.setdata(1066);
s2.setdata(1776);
هذه العبارات لا تشبه استدعاءات الدوال العادية. لماذا ترتبط أسماء الكائنات s1 و s2 بأسماء الوظائف بنقطة period ؟ يتم استخدام بناء الجملة الغريب هذا لاستدعاء دالة عضو مرتبطة associated with بكائن معين specific object . لأن setdata() هي دالة عضو في الفئة smallobj ، يجب دائمًا استدعاؤها مرتبطة يتعلق بكائن من هذه الفئة. ليس من المنطقي القول
- الكود:
setdata(1066);
لاستخدام دالة عضو ، يقوم عامل النقطة (.) (الفترة period ) بربط (بتوصيل) connect اسم الكائن ودالة العضو. يشبه بناء الجملة الطريقة التي نشير بها إلى أعضاء الهيكل ، لكن الأقواس تشير إلى أننا ننفذ دالة عضو بدلاً من الإشارة إلى عنصر بيانات. (يُطلق على عامل النقطة أيضًا عامل الوصول إلى عضو الفئة class member access ).
الاستدعاء الأول للدالة setdata() :
- الكود:
s1.setdata(1066);
ينفذ الدالة العضو setdata() للكائن s1. تقوم هذه الدالة بتعيين (بضبط) set المتغير somedata في الكائن s1 على القيمة 1066. الاستدعاء الثانى :
- الكود:
s2.setdata(1776);
يؤدي إلى تعيين المتغير somedata في الكائن s2 على القيمة 1776. الآن لدينا كائنان لهما المتغيرات somedata لها قيم مختلفة ، كما هو مبين في الشكل .
الشكل يبين كائنان من الفئة smallobj
وبالمثل ، سيؤدي الاستدعاءان التاليان للدالة showdata() إلى أن يعرض الكائنان قيمهما:
- الكود:
s1.showdata();
s2.showdata();
الرسائل Messages
تشير بعض اللغات الموجهة للكائنات إلى استدعاءات الدوال الأعضاء كرسائل messages . وبالتالي فإن الاستدعاء :
- الكود:
s1.showdata();
يمكن التفكير فيه كإرسال رسالة sending a message إلى الكائن s1 لإخباره بإظهار بياناته. مصطلح الرسالة ليس مصطلحًا رسميًا في لغة C++ ، لكن من المفيد أن نأخذه في الاعتبار عند مناقشتنا الدوال الأعضاء.
الحديث عن الرسائل يؤكد أن الكائنات كيانات منفصلة وأننا نتواصل معها من خلال استدعاء الدوال الأعضاء. بالإشارة إلى التشابه مع تنظيم الشركة في الدرس الأول ، من المفضل إرسال رسالة إلى السكرتير في قسم المبيعات لطلب قائمة بالمنتجات التي تباع في منطقة التوزيع الجنوبية الغربية.
رد: البرمجة الموجهة للكائن Object-Oriented Programming
كائنات C++ ككائنات فعلية (طبيعية) C++ Objects as Physical Objects
في العديد من مواقف البرمجة ، تمثل الكائنات الموجودة في البرامج كائنات مادية (طبيعية) : أشياء يمكن الشعور بها أو رؤيتها. توفر هذه الحالات أمثلة حية على التطابق (التشابه) البرنامج والعالم الحقيقي. سننظر في حالة من هذه الحالات : أجزاء القطعة widget parts .
أجزاء القطعة ككائنات Widget Parts as Objects
الفئة smallobj في المثال الأخير بها عنصر بيانات واحد فقط. دعونا نلقي نظرة على مثال لفئة أكثر طموحًا إلى حد ما. سنقوم بإنشاء فئة class بناءً على هيكل لمخزون أجزاء قطعة widget parts . فيما يلي القائمة OBJPART:
يعرض هذا البرنامج الفئة part . بدلاً من عنصر بيانات data item واحد ، كما كان لدى SMALLOBJ ، تحتوي هذه الفئة على ثلاثة : modelnumber و partnumber و cost. توفر دالة العضو setpart()بمفردها ، القيم لجميع عناصر البيانات الثلاثة في آن واحد. الدالة الأخرى ، showpart() ، تعرض القيم المخزنة في العناصر الثلاثة.
في هذا المثال ، يتم إنشاء كائن واحد فقط من النوع part هو : part1 . تقوم دالة العضو setpart() بتعيين عناصر البيانات الثلاثة في هذا الجزء إلى القيم 6244 و 373 و 217.55. تعرض الدالة العضو showpart() هذه القيم. إليك الإخراج:
هذا مثال أكثر واقعية إلى حد ما من SMALLOBJ. إذا كنت تقوم بتصميم برنامج جرد (مخزون) inventory ، فقد ترغب بالفعل في إنشاء فئة تشبه part . إنه مثال لكائن C++ يمثل كائنًا ماديًا في العالم الحقيقي - widget part .
في العديد من مواقف البرمجة ، تمثل الكائنات الموجودة في البرامج كائنات مادية (طبيعية) : أشياء يمكن الشعور بها أو رؤيتها. توفر هذه الحالات أمثلة حية على التطابق (التشابه) البرنامج والعالم الحقيقي. سننظر في حالة من هذه الحالات : أجزاء القطعة widget parts .
أجزاء القطعة ككائنات Widget Parts as Objects
الفئة smallobj في المثال الأخير بها عنصر بيانات واحد فقط. دعونا نلقي نظرة على مثال لفئة أكثر طموحًا إلى حد ما. سنقوم بإنشاء فئة class بناءً على هيكل لمخزون أجزاء قطعة widget parts . فيما يلي القائمة OBJPART:
- الكود:
// objpart.cpp
// widget part as an object
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class part //define class
{
private:
int modelnumber; //ID number of widget
int partnumber; //ID number of widget part
float cost; //cost of part
public:
void setpart(int mn, int pn, float c) //set data
{
modelnumber = mn;
partnumber = pn;
cost = c;
}
void showpart() //display data
{
cout << “Model “ << modelnumber;
cout << “, part “ << partnumber;
cout << “, costs $” << cost << endl;
}
};
////////////////////////////////////////////////////////////////
int main()
{
part part1; //define object
// of class part
part1.setpart(6244, 373, 217.55F); //call member function
part1.showpart(); //call member function
return 0;
}
يعرض هذا البرنامج الفئة part . بدلاً من عنصر بيانات data item واحد ، كما كان لدى SMALLOBJ ، تحتوي هذه الفئة على ثلاثة : modelnumber و partnumber و cost. توفر دالة العضو setpart()بمفردها ، القيم لجميع عناصر البيانات الثلاثة في آن واحد. الدالة الأخرى ، showpart() ، تعرض القيم المخزنة في العناصر الثلاثة.
في هذا المثال ، يتم إنشاء كائن واحد فقط من النوع part هو : part1 . تقوم دالة العضو setpart() بتعيين عناصر البيانات الثلاثة في هذا الجزء إلى القيم 6244 و 373 و 217.55. تعرض الدالة العضو showpart() هذه القيم. إليك الإخراج:
- الكود:
Model 6244, part 373, costs $217.55
هذا مثال أكثر واقعية إلى حد ما من SMALLOBJ. إذا كنت تقوم بتصميم برنامج جرد (مخزون) inventory ، فقد ترغب بالفعل في إنشاء فئة تشبه part . إنه مثال لكائن C++ يمثل كائنًا ماديًا في العالم الحقيقي - widget part .
رد: البرمجة الموجهة للكائن Object-Oriented Programming
كائنات C++ كأنواع بيانات C++ Objects as Data Types
في ما يلي نوع آخر من الكائنات التي يمكن أن تمثلها عناصر C++ : متغيرات نوع البيانات المعرفة من قبل المستخدم.
سنستخدم الكائنات لتمثيل المسافات المقاسة في النظام الإنجليزى . فيما يلي القائمة ENGLOBJ:
في هذا البرنامج ، تحتوي الفئة Distance على عنصرين من البيانات ، feet و inches . الفئة Distance لها أيضًا ثلاث دوال لأعضاء : الدالة setdist() ، والتى تستخدم الوسائط لتعيين feet و inches ؛ والدالة getdist() ، والتى تحصل على قيم feet و inches من المستخدم في لوحة المفاتيح ؛ والدالة showdist() ، التى تعرض المسافة في تنسيق feet- inches .
وبالتالي يمكن تعيين set قيمة كائن من الفئة Distance بأي من طريقتين. في الدالة main() ، نعرف define كائنين من الفئة Distance هما : dist1 و dist2. يتم إعطاء الأول القيمة باستخدام دالة العضو setdist() مع الوسيطتين 11 و 6.25 ، ويتم إعطاء الثانى القيمة التي يوفرها المستخدم. إليك نموذج تفاعلي مع البرنامج:
في ما يلي نوع آخر من الكائنات التي يمكن أن تمثلها عناصر C++ : متغيرات نوع البيانات المعرفة من قبل المستخدم.
سنستخدم الكائنات لتمثيل المسافات المقاسة في النظام الإنجليزى . فيما يلي القائمة ENGLOBJ:
- الكود:
// englobj.cpp
// objects using English measurements
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Distance //English Distance class
{
private:
int feet; // data items
float inches;
public:
void setdist(int ft, float in) //set Distance to args
{ feet = ft; inches = in; }
void getdist() //get length from user
{
cout << “\nEnter feet: “; cin >> feet;
cout << “Enter inches: “; cin >> inches;
}
void showdist() //display distance
{ cout << feet << “\’-” << inches << ‘\”’; }
};
////////////////////////////////////////////////////////////////
int main()
{
Distance dist1, dist2; //define two lengths (objects), as Data Type
dist1.setdist(11, 6.25); //set dist1
dist2.getdist(); //get dist2 from user
//display lengths
cout << “\ndist1 = “; dist1.showdist();
cout << “\ndist2 = “; dist2.showdist();
cout << endl;
return 0;
}
في هذا البرنامج ، تحتوي الفئة Distance على عنصرين من البيانات ، feet و inches . الفئة Distance لها أيضًا ثلاث دوال لأعضاء : الدالة setdist() ، والتى تستخدم الوسائط لتعيين feet و inches ؛ والدالة getdist() ، والتى تحصل على قيم feet و inches من المستخدم في لوحة المفاتيح ؛ والدالة showdist() ، التى تعرض المسافة في تنسيق feet- inches .
وبالتالي يمكن تعيين set قيمة كائن من الفئة Distance بأي من طريقتين. في الدالة main() ، نعرف define كائنين من الفئة Distance هما : dist1 و dist2. يتم إعطاء الأول القيمة باستخدام دالة العضو setdist() مع الوسيطتين 11 و 6.25 ، ويتم إعطاء الثانى القيمة التي يوفرها المستخدم. إليك نموذج تفاعلي مع البرنامج:
- الكود:
Enter feet: 10
Enter inches: 4.75
dist1 = 11’-6.25” ← provided by arguments
dist2 = 10’-4.75” ← input by the user
المنشىء (المشيد - البناء) Constructor
المنشىء (المشيد - البناء) Constructor
يوضح المثال ENGLOBJ طريقتين والتى يمكن بهما استخدام دوال الأعضاء لإعطاء قيم إلى عناصر البيانات في كائن. ومع ذلك ، يكون من المريح أحيانًا أن يتمكن كائن من تهيئة نفسه عند إنشائه لأول مرة ، دون الحاجة إلى استدعاء منفصل لدالة العضو. تتم التهيئة التلقائية باستخدام دالة عضو خاصة تسمى المنشئ constructor . المُنشئ constructor عبارة عن دالة عضو يتم تنفيذها تلقائيًا عند إنشاء كائن. (يتم أحيانًا اختصار المصطلح "مُنشئ" ctor ، خاصةً في التعليقات في قوائم البرنامج.)
مثال العداد A Counter Example
كمثال ، سننشئ فئة من الكائنات التي قد تكون مفيدة كعنصر برمجة للأغراض العامة. العداد counter هو متغير يعد الأشياء. ربما يقوم بعد عمليات الوصول إلى الملفات ، أو عدد المرات التي يضغط فيها المستخدم على مفتاح Enter ، أو عدد العملاء الذين يدخلون البنك. في كل مرة يحدث مثل هذا الحدث ، يتم زيادة العداد (تتم إضافة 1 إليه). يمكن أيضًا الوصول إلى العداد لإيجاد العدد الحالي.
لنفترض أن هذا العداد مهم في البرنامج ويجب الوصول إليه من خلال العديد من الدوال المختلفة. في اللغات الإجرائية مثل C ، قد يتم تطبيق العداد كمتغير عمومى global . ومع ذلك ، كما أشرنا سابقا ، فإن المتغيرات العمومية تعقد تصميم البرنامج ويمكن تعديلها عن طريق الخطأ. يوفر هذا المثال ، COUNTER ، متغير عداد counter لا يمكن تعديله إلا من خلال دوال الأعضاء.
تحتوي الفئة Counter على عضو بيانات واحد : count ، من النوع unsigned int (لأن count يكون دائمًا موجبًا). ويحتوي على ثلاث دوال أعضاء : المنشىء Counter() ، والتي سننظر إليها بعد لحظة ؛ و inc_count() ، التى تضيف 1 إلى count ؛ و get_count() ، والتي تُرجع القيمة الحالية للعدد count .
التهيئة التلقائية Automatic Initialization
عندما يتم إنشاء كائن من النوع Counter لأول مرة ، نريد تهيئة عدده count إلى 0. بعد كل شيء ، تبدأ معظم العدادات من 0. يمكننا توفير الدالة set_count() للقيام بذلك واستدعاءها باستخدام الوسيط 0 ، أو يمكننا توفير الدالة zero_count() ، والتي من شأنها دائمًا تعيين العدد count إلى 0.
ومع ذلك ، يجب تنفيذ هذه الدوال في كل مرة ننشىء فيها كائن Counter .
هذا يكون عرضة للخطأ ، لأن المبرمج قد ينسى تهيئة الكائن بعد إنشائه. إنه أكثر موثوقية وملاءمة ، خاصةً عندما يكون هناك عدد كبير من الكائنات لفئة معينة ، بحيث يتسبب كل كائن في التهيئة عند إنشائه. في الفئة Counter ، يقوم المنشئ Counter() بهذا. يتم استدعاء هذه الدالة تلقائيًا عند إنشاء كائن جديد من النوع Counter . وبالتالي في الدالة main() فإن العبارة
تنشىء كائنين من نوع Counter . عند إنشاء كل منها ، يتم تنفيذ المنشئ الخاص بها ، Counter() .
تقوم هذه الدالة بضبط (تعيين) المتغير count على 0. وبالتالي فإن تأثير هذه العبارة الفردية ليس فقط لإنشاء كائنين ، ولكن أيضًا لتهيئة المتغيرات count الخاصة بها إلى 0.
نفس اسم الفئة Same Name as the Class
هناك بعض الجوانب غير العادية لدوال المنشئ constructor . أولاً ، ليس من قبيل المصادفة أن يكون لديهم نفس الاسم (Counter في هذا المثال) تمامًا مثل الفئة التي ينتمون إليها ( تكون عضو فيها) . هذه هى الطريقة الأولى التى يعرف بها المترجم أنهم منشئين.
ثانياً ، لا يتم استخدام نوع الإرجاع للمنشئين . لما لا؟ نظرًا لأن المنشئ يتم استدعاؤه تلقائيًا بواسطة النظام ، لا يوجد برنامج لإعادة أي شيء إليه ؛ القيمة المعادة لن تكون منطقية. هذه هي الطريقة الثانية التي يعرف بها المترجم أنهم منشئين.
قائمة المهيئ Initializer List
إحدى أكثر المهام شيوعًا التي يقوم بها المنشئ هي تهيئة أعضاء البيانات. في الفئة Counter يجب على المُنشئ تهيئة العضو count إلى 0. قد تعتقد أن هذا سيتم في جسم دوال المُنشئ ، مثل هذا:
ومع ذلك ، ليس هذا هو النهج المفضل (على الرغم من أنه يعمل). إليك كيفية تهيئة عضو بيانات:
تتم التهيئة بعد معلن الدالة العضو ولكن قبل جسم الدالة. مسبوقًا بنقطتين ( . يتم وضع القيمة بين قوسين () بعد بيانات العضو.
إذا كان يجب تهيئة أعضاء متعددين ، فسيتم فصلهم بفواصل. والنتيجة هي قائمة المهيئ initializer list (تسمى أحيانًا بأسماء أخرى ، مثل قائمة تهيئة الأعضاء member-initialization list ).
لماذا لا يتم تهيئة الأعضاء في جسم المنشئ؟ الأسباب معقدة ، ولكن يجب أن تتعلق بحقيقة أن الأعضاء الذين تتم تهيئتهم في قائمة المهىء يُمنحون قيمة قبل أن يبدأ المُنشئ في التنفيذ. هذا مهم في بعض الحالات. على سبيل المثال ، تعد قائمة المهيئ هي الطريقة الوحيدة لتهيئة بيانات ومراجع عضو const.
يجب تنفيذ الإجراءات الأكثر تعقيدًا من التهيئة البسيطة في جسم المنشئ ، كما هو الحال مع الدوال العادية.
خرج العداد Counter Output
يعالج الجزء main() من هذا البرنامج الفئة ع Counter من خلال إنشاء عدادين ، c1 و c2.
تتسبب العدادات في عرض قيمها الأولية ، والتي - حسب ترتيب المُنشئ – هي 0. ثم يزيد c1 مرة واحدة و c2 مرتين ، ويؤدي مرة أخرى تتسبب العدادات فى عرض أنفسهم. إليك الإخراج:
إذا لم يكن هذا دليلًا كافيًا على أن المُنشئ يعمل كما هو معلن ، فيمكننا إعادة كتابة المنشئ لطباعة رسالة عند تنفيذه.
الآن يبدو إخراج البرنامج كما يلي:
كما ترى ، يتم تنفيذ constructor مرتين – مرة من أجل c1 ومرة من أجل c2 عندما يتم تنفيذ العبارة التالية فى الدالة main() :
يوضح المثال ENGLOBJ طريقتين والتى يمكن بهما استخدام دوال الأعضاء لإعطاء قيم إلى عناصر البيانات في كائن. ومع ذلك ، يكون من المريح أحيانًا أن يتمكن كائن من تهيئة نفسه عند إنشائه لأول مرة ، دون الحاجة إلى استدعاء منفصل لدالة العضو. تتم التهيئة التلقائية باستخدام دالة عضو خاصة تسمى المنشئ constructor . المُنشئ constructor عبارة عن دالة عضو يتم تنفيذها تلقائيًا عند إنشاء كائن. (يتم أحيانًا اختصار المصطلح "مُنشئ" ctor ، خاصةً في التعليقات في قوائم البرنامج.)
مثال العداد A Counter Example
كمثال ، سننشئ فئة من الكائنات التي قد تكون مفيدة كعنصر برمجة للأغراض العامة. العداد counter هو متغير يعد الأشياء. ربما يقوم بعد عمليات الوصول إلى الملفات ، أو عدد المرات التي يضغط فيها المستخدم على مفتاح Enter ، أو عدد العملاء الذين يدخلون البنك. في كل مرة يحدث مثل هذا الحدث ، يتم زيادة العداد (تتم إضافة 1 إليه). يمكن أيضًا الوصول إلى العداد لإيجاد العدد الحالي.
لنفترض أن هذا العداد مهم في البرنامج ويجب الوصول إليه من خلال العديد من الدوال المختلفة. في اللغات الإجرائية مثل C ، قد يتم تطبيق العداد كمتغير عمومى global . ومع ذلك ، كما أشرنا سابقا ، فإن المتغيرات العمومية تعقد تصميم البرنامج ويمكن تعديلها عن طريق الخطأ. يوفر هذا المثال ، COUNTER ، متغير عداد counter لا يمكن تعديله إلا من خلال دوال الأعضاء.
- الكود:
// counter.cpp
// object represents a counter variable
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Counter
{
private:
unsigned int count; //count
public:
Counter() : count(0) //constructor
{ /*empty body*/ }
void inc_count() //increment count
{ count++; }
int get_count() //return count
{ return count; }
};
////////////////////////////////////////////////////////////////
int main()
{
Counter c1, c2; //define and initialize
cout << “\nc1=” << c1.get_count(); //display
cout << “\nc2=” << c2.get_count();
c1.inc_count(); //increment c1
c2.inc_count(); //increment c2
c2.inc_count(); //increment c2
cout << “\nc1=” << c1.get_count(); //display again
cout << “\nc2=” << c2.get_count();
cout << endl;
return 0;
}
تحتوي الفئة Counter على عضو بيانات واحد : count ، من النوع unsigned int (لأن count يكون دائمًا موجبًا). ويحتوي على ثلاث دوال أعضاء : المنشىء Counter() ، والتي سننظر إليها بعد لحظة ؛ و inc_count() ، التى تضيف 1 إلى count ؛ و get_count() ، والتي تُرجع القيمة الحالية للعدد count .
التهيئة التلقائية Automatic Initialization
عندما يتم إنشاء كائن من النوع Counter لأول مرة ، نريد تهيئة عدده count إلى 0. بعد كل شيء ، تبدأ معظم العدادات من 0. يمكننا توفير الدالة set_count() للقيام بذلك واستدعاءها باستخدام الوسيط 0 ، أو يمكننا توفير الدالة zero_count() ، والتي من شأنها دائمًا تعيين العدد count إلى 0.
ومع ذلك ، يجب تنفيذ هذه الدوال في كل مرة ننشىء فيها كائن Counter .
- الكود:
Counter c1; //every time we do this,
c1.zero_count(); //we must do this too
هذا يكون عرضة للخطأ ، لأن المبرمج قد ينسى تهيئة الكائن بعد إنشائه. إنه أكثر موثوقية وملاءمة ، خاصةً عندما يكون هناك عدد كبير من الكائنات لفئة معينة ، بحيث يتسبب كل كائن في التهيئة عند إنشائه. في الفئة Counter ، يقوم المنشئ Counter() بهذا. يتم استدعاء هذه الدالة تلقائيًا عند إنشاء كائن جديد من النوع Counter . وبالتالي في الدالة main() فإن العبارة
- الكود:
Counter c1, c2;
تنشىء كائنين من نوع Counter . عند إنشاء كل منها ، يتم تنفيذ المنشئ الخاص بها ، Counter() .
تقوم هذه الدالة بضبط (تعيين) المتغير count على 0. وبالتالي فإن تأثير هذه العبارة الفردية ليس فقط لإنشاء كائنين ، ولكن أيضًا لتهيئة المتغيرات count الخاصة بها إلى 0.
نفس اسم الفئة Same Name as the Class
هناك بعض الجوانب غير العادية لدوال المنشئ constructor . أولاً ، ليس من قبيل المصادفة أن يكون لديهم نفس الاسم (Counter في هذا المثال) تمامًا مثل الفئة التي ينتمون إليها ( تكون عضو فيها) . هذه هى الطريقة الأولى التى يعرف بها المترجم أنهم منشئين.
ثانياً ، لا يتم استخدام نوع الإرجاع للمنشئين . لما لا؟ نظرًا لأن المنشئ يتم استدعاؤه تلقائيًا بواسطة النظام ، لا يوجد برنامج لإعادة أي شيء إليه ؛ القيمة المعادة لن تكون منطقية. هذه هي الطريقة الثانية التي يعرف بها المترجم أنهم منشئين.
قائمة المهيئ Initializer List
إحدى أكثر المهام شيوعًا التي يقوم بها المنشئ هي تهيئة أعضاء البيانات. في الفئة Counter يجب على المُنشئ تهيئة العضو count إلى 0. قد تعتقد أن هذا سيتم في جسم دوال المُنشئ ، مثل هذا:
- الكود:
Counter()
{ count = 0; }
ومع ذلك ، ليس هذا هو النهج المفضل (على الرغم من أنه يعمل). إليك كيفية تهيئة عضو بيانات:
- الكود:
Counter() : count(0) //constructor
{ /*empty body*/ }
تتم التهيئة بعد معلن الدالة العضو ولكن قبل جسم الدالة. مسبوقًا بنقطتين ( . يتم وضع القيمة بين قوسين () بعد بيانات العضو.
إذا كان يجب تهيئة أعضاء متعددين ، فسيتم فصلهم بفواصل. والنتيجة هي قائمة المهيئ initializer list (تسمى أحيانًا بأسماء أخرى ، مثل قائمة تهيئة الأعضاء member-initialization list ).
- الكود:
someClass() : m1(7), m2(33), m2(4) ← initializer list
{ }
لماذا لا يتم تهيئة الأعضاء في جسم المنشئ؟ الأسباب معقدة ، ولكن يجب أن تتعلق بحقيقة أن الأعضاء الذين تتم تهيئتهم في قائمة المهىء يُمنحون قيمة قبل أن يبدأ المُنشئ في التنفيذ. هذا مهم في بعض الحالات. على سبيل المثال ، تعد قائمة المهيئ هي الطريقة الوحيدة لتهيئة بيانات ومراجع عضو const.
يجب تنفيذ الإجراءات الأكثر تعقيدًا من التهيئة البسيطة في جسم المنشئ ، كما هو الحال مع الدوال العادية.
خرج العداد Counter Output
يعالج الجزء main() من هذا البرنامج الفئة ع Counter من خلال إنشاء عدادين ، c1 و c2.
تتسبب العدادات في عرض قيمها الأولية ، والتي - حسب ترتيب المُنشئ – هي 0. ثم يزيد c1 مرة واحدة و c2 مرتين ، ويؤدي مرة أخرى تتسبب العدادات فى عرض أنفسهم. إليك الإخراج:
- الكود:
c1=0
c2=0
c1=1
c2=2
إذا لم يكن هذا دليلًا كافيًا على أن المُنشئ يعمل كما هو معلن ، فيمكننا إعادة كتابة المنشئ لطباعة رسالة عند تنفيذه.
- الكود:
الآن يبدو إخراج البرنامج كما يلي:
- الكود:
I’m the constructor
I’m the constructor
c1=0
c2=0
c1=1
c2=2
كما ترى ، يتم تنفيذ constructor مرتين – مرة من أجل c1 ومرة من أجل c2 عندما يتم تنفيذ العبارة التالية فى الدالة main() :
- الكود:
Counter c1, c2;
رد: البرمجة الموجهة للكائن Object-Oriented Programming
البرمجةالموجهة للكائن OBJECT ORIENTED PROGRAMMING
1.1 مقدمة
منذ نشأت لغات البرمجة حدثت العديد من المشاكل مع لغة البرمجة الإجرائية procedural . في لغة البرمجة الإجرائية ، كان التركيز على فعل الأشياء التي كانت تمثل وظائف (دوال) ، وكانت تتألف من متغيرات عمومية global ، وكان هناك دائمًا إمكانية للتغيير العرضي في البيانات. وبالتالي ، تم تطوير نظام جديد للبرمجة اسمه البرمجة الموجهة للكائن Object Oriented Programming . باختصار يطلق عليها "OOP". تمكن OOP المبرمجين من تجميع البيانات والكود الذي يستخدم البيانات معًا في وحدات منفصلة. في OOP يتم إعطاء الأهمية للكائن بصرف النظر عن الإجراء.
يتم تعريف الكائن بواسطة مصطلحين : السمات attributes والسلوكيات behaviors . إذا نظرت إلى شخص person وتصورته ككائن object ، فستجد أن لدى شخص ما سمات ، مثل لون العين والعمر والطول وما إلى ذلك. لدى الشخص أيضًا سلوكيات ، مثل المشي والتحدث والتنفس وما إلى ذلك. الكائن في تعريفه الأساسي هو كيان entity يحتوي على كل من both البيانات data والسلوك behavior . الكلمة both هي الفرق الرئيسي بين منهجية البرمجة الأكثر تقليدية ، والبرمجة الإجرائية ، و OOP.
في البرمجة الإجرائية procedural programming ، يتم وضع الكود في دوال functions أو إجراءات procedures مختلفة (مستقلة) تمامًا.
من الناحية المثالية ، كما هو مبين في الشكل 1.1 ، تصبح هذه الإجراءات "صناديق سوداء" "black boxes," ، حيث تدخل المدخلات وتخرج المخرجات. يتم وضع البيانات Data في هياكل منفصلة ، ويتم معالجتها بواسطة هذه الدوال أو الإجراءات.
Figure 1.1 Black boxes.
1.1.1 الفرق بين OOP والبرمجة الإجرائية Difference between OOP and Procedural Programming
في التصميم الموجه للكائن ، يتم تضمين السمات attributes والسلوك behavior داخل كائن واحد ، بينما في التصميم الإجرائي أو المهيكل structured ، يتم فصل السمات والسلوك عادةً.
كما هو موضح في الشكل 1.2 ، في البرمجة الإجرائية ، يتم فصل البيانات عن الإجراءات ، وأحيانًا تكون البيانات عمومية ، لذلك من السهل تعديل البيانات الخارجة عن نطاقك. هذا يعني أن الوصول إلى البيانات لا يمكن التحكم فيه ولا يمكن التنبؤ به (على سبيل المثال ، قد يكون للعديد من الوظائف إمكانية الوصول إلى البيانات العمومية ). علاوة على ذلك ، لأنه ليس لديك التحكم في من يمكنه الوصول إلى البيانات ؛ الاختبار وتصحيح الأخطاء أكثر صعوبة بكثير. تعالج الكائنات هذه المشكلات من خلال دمج البيانات والسلوك في حزمة أنيقة وكاملة.
Figure 1.2 Using global data.
1.2 الخصائص الأساسية للبرمجة الموجه للكائن Basic Features of Object Oriented Programming
• التركيز على البيانات
• تتبع النهج التصاعدي bottom-up في تصميم البرنامج
• لديها مفاهيم مثل إخفاء البيانات data hiding التى تمنع التغيير العرضي للبيانات
• لها خصائص مثل
• تعدد الأشكال Polymorphism
• الميراث Inheritance
• التغليف Encapsulation
هذه الخصائص موضحة لاحقًا في هذا الدرس .
1.3 الفئات والكائنات Classes & Objects
للكائن object علاقة بالفئة class مثل علاقة المتغير بنوع البيانات. باختصار الكائن هو مثيل instance لفئة. الفئة class هي نوع بيانات معرف من قبل المستخدم يستخدم لتنفيذ (تحقيق) implement كائن مجرد . الفئة تحتوي على أعضاء من ثلاثة أنواع: "خاص" ‘private’ أو "عام" ‘public’ أو "محمي" ‘protected’ افتراضيًا ، يكون أعضاء بيانات الفئة من نوع الأعضاء الخاصة ‘private’ . تُعرف محتويات الفئة كأعضاء members في الفئة ، وتعرف البيانات المعلنة داخل الفئة باسم أعضاء البيانات data members والدوال المضمنة داخل الفئة تعرف باسم الدوال الأعضاء member functions .
يُقال إن الكائن هو مثيل instance لفئة ، بالطريقة نفسها "لوحة المفاتيح" و "الماوس" ينتميان إلى فئة "الأجهزة" ‘hardware’، أو "أنا" ‘me’ و "أنت" ‘you’ مثيلات لفئة "الإنسان" ‘HUMAN' .
Figure 1.3: Classes a collection of data and functions
تُعرف الفئة التي لا تحتوي على كائن باسم الفئة المجردة Abstract class والفئة التي تحتوي على كائن (كائنات) تعرف باسم فئة واقعية (متماسكة) Concrete . كل كائن له هويته identity الخاصة ، والحالة state والسلوك behavior . الهوية Identity هي خاصية الكائن ، التى تميزه عن الكائنات الأخرى. تشير الخصائص الثابتة والديناميكية المرتبطة بالكائن إلى حالة state الكائن . تعرض العمليات / الدوال المرتبطة بالكائن سلوك behavior الكائن.
يمكن الإعلان عن فئة class باستخدام بناء الجملة التالي:
على سبيل المثال :
في المثال أعلاه ، Steve و Jordanهما إعلانان لكائنان . يمكن الاحتفاظ بالأعضاء في أي من أوضاع إمكانية الوصول الثلاثة الخاصة والعامة والمحمية. يمكن للأعضاء في وضع الرؤية العامة public للفئة الوصول إلى كائنات الفئة بينما الأعضاء في وضع إمكانية الوصول الخاصة private لا يمكنهم الوصول إلى كائنات الفئة. يمكن الوصول إليها فقط داخل الفئة للدوال الأعضاء في الفئة .
ملاحظة: سيتم شرح الأعضاء المحميين Protected members لاحقًا في الدرس الثانى بعنوان "الميراث" ‘Inheritance’ .
يوضح البرنامج التالى استخدام الفئات والكائنات :
في المثال أعلاه ، يمكن للمرء أن يرى أن الفئة hospital يتم تعريفها بما يلى :
1- ثلاثة من أعضاء البيانات الخاصة patientno و wardno و patient_name ؛ و
2- دالتان عضوان عموميين register_patient() و showstatus() .
يمكن تعريف الدوال الأعضاء داخل الفئة وكذلك خارج الفئة كما هو موضح في المثال ، يتم تعريف الدالة العضو showstatus() داخل الفئة بينما يتم تعريف الدالة العضو register_patient() خارج الفئة باستخدام عامل دقة النطاق (: scope resolution operator مع اسم الفئة التي تنتمي إليها hospital::register_patient() . الشكل 1.4 يوضح استخدام عامل دقة النطاق. يمكن لكائنات الفئة استدعاء هاتين الدالتين بنفس الطريقة. عمومًا ، يتم تعريف الدوال ذات السطور المفردة داخل الفئة ، ويتم تعريف دوال المتعددة الأسطر والدوال لتي تحتوي على هياكل التحكم (if … else أو حلقات while ) خارج الفئة ليكون لها وضوح في فهم سلوك الفئة .
Figure 1.4: A function declared outside the class
ملاحظة: يعتمد حجم الكائن (بالبايت) على أعضاء البيانات الموجودين في الفئة التي ينتمي إليها. في المثال أعلاه ، يشغل الكائن p1 على 24 بايت.
أخطاء البرمجة الشائعة
• الإعلان عن الدوال الأعضاء خارج تعريفات الفئة دون نطاق عامل دقة المدى (: سيؤدي إلى خطأ.
• يجب أن تنتهي تعريفات الفئة بفاصلة منقوطة. تجاهل هذا سيؤدي إلى خطأ .
1.1 مقدمة
منذ نشأت لغات البرمجة حدثت العديد من المشاكل مع لغة البرمجة الإجرائية procedural . في لغة البرمجة الإجرائية ، كان التركيز على فعل الأشياء التي كانت تمثل وظائف (دوال) ، وكانت تتألف من متغيرات عمومية global ، وكان هناك دائمًا إمكانية للتغيير العرضي في البيانات. وبالتالي ، تم تطوير نظام جديد للبرمجة اسمه البرمجة الموجهة للكائن Object Oriented Programming . باختصار يطلق عليها "OOP". تمكن OOP المبرمجين من تجميع البيانات والكود الذي يستخدم البيانات معًا في وحدات منفصلة. في OOP يتم إعطاء الأهمية للكائن بصرف النظر عن الإجراء.
يتم تعريف الكائن بواسطة مصطلحين : السمات attributes والسلوكيات behaviors . إذا نظرت إلى شخص person وتصورته ككائن object ، فستجد أن لدى شخص ما سمات ، مثل لون العين والعمر والطول وما إلى ذلك. لدى الشخص أيضًا سلوكيات ، مثل المشي والتحدث والتنفس وما إلى ذلك. الكائن في تعريفه الأساسي هو كيان entity يحتوي على كل من both البيانات data والسلوك behavior . الكلمة both هي الفرق الرئيسي بين منهجية البرمجة الأكثر تقليدية ، والبرمجة الإجرائية ، و OOP.
في البرمجة الإجرائية procedural programming ، يتم وضع الكود في دوال functions أو إجراءات procedures مختلفة (مستقلة) تمامًا.
من الناحية المثالية ، كما هو مبين في الشكل 1.1 ، تصبح هذه الإجراءات "صناديق سوداء" "black boxes," ، حيث تدخل المدخلات وتخرج المخرجات. يتم وضع البيانات Data في هياكل منفصلة ، ويتم معالجتها بواسطة هذه الدوال أو الإجراءات.
Figure 1.1 Black boxes.
1.1.1 الفرق بين OOP والبرمجة الإجرائية Difference between OOP and Procedural Programming
في التصميم الموجه للكائن ، يتم تضمين السمات attributes والسلوك behavior داخل كائن واحد ، بينما في التصميم الإجرائي أو المهيكل structured ، يتم فصل السمات والسلوك عادةً.
كما هو موضح في الشكل 1.2 ، في البرمجة الإجرائية ، يتم فصل البيانات عن الإجراءات ، وأحيانًا تكون البيانات عمومية ، لذلك من السهل تعديل البيانات الخارجة عن نطاقك. هذا يعني أن الوصول إلى البيانات لا يمكن التحكم فيه ولا يمكن التنبؤ به (على سبيل المثال ، قد يكون للعديد من الوظائف إمكانية الوصول إلى البيانات العمومية ). علاوة على ذلك ، لأنه ليس لديك التحكم في من يمكنه الوصول إلى البيانات ؛ الاختبار وتصحيح الأخطاء أكثر صعوبة بكثير. تعالج الكائنات هذه المشكلات من خلال دمج البيانات والسلوك في حزمة أنيقة وكاملة.
Figure 1.2 Using global data.
1.2 الخصائص الأساسية للبرمجة الموجه للكائن Basic Features of Object Oriented Programming
• التركيز على البيانات
• تتبع النهج التصاعدي bottom-up في تصميم البرنامج
• لديها مفاهيم مثل إخفاء البيانات data hiding التى تمنع التغيير العرضي للبيانات
• لها خصائص مثل
• تعدد الأشكال Polymorphism
• الميراث Inheritance
• التغليف Encapsulation
هذه الخصائص موضحة لاحقًا في هذا الدرس .
1.3 الفئات والكائنات Classes & Objects
للكائن object علاقة بالفئة class مثل علاقة المتغير بنوع البيانات. باختصار الكائن هو مثيل instance لفئة. الفئة class هي نوع بيانات معرف من قبل المستخدم يستخدم لتنفيذ (تحقيق) implement كائن مجرد . الفئة تحتوي على أعضاء من ثلاثة أنواع: "خاص" ‘private’ أو "عام" ‘public’ أو "محمي" ‘protected’ افتراضيًا ، يكون أعضاء بيانات الفئة من نوع الأعضاء الخاصة ‘private’ . تُعرف محتويات الفئة كأعضاء members في الفئة ، وتعرف البيانات المعلنة داخل الفئة باسم أعضاء البيانات data members والدوال المضمنة داخل الفئة تعرف باسم الدوال الأعضاء member functions .
يُقال إن الكائن هو مثيل instance لفئة ، بالطريقة نفسها "لوحة المفاتيح" و "الماوس" ينتميان إلى فئة "الأجهزة" ‘hardware’، أو "أنا" ‘me’ و "أنت" ‘you’ مثيلات لفئة "الإنسان" ‘HUMAN' .
Figure 1.3: Classes a collection of data and functions
تُعرف الفئة التي لا تحتوي على كائن باسم الفئة المجردة Abstract class والفئة التي تحتوي على كائن (كائنات) تعرف باسم فئة واقعية (متماسكة) Concrete . كل كائن له هويته identity الخاصة ، والحالة state والسلوك behavior . الهوية Identity هي خاصية الكائن ، التى تميزه عن الكائنات الأخرى. تشير الخصائص الثابتة والديناميكية المرتبطة بالكائن إلى حالة state الكائن . تعرض العمليات / الدوال المرتبطة بالكائن سلوك behavior الكائن.
يمكن الإعلان عن فئة class باستخدام بناء الجملة التالي:
- الكود:
class Class-name
{
private: // its optional to write private access specifier
data-member;
data-member;
member-function
protected:
data-member;
data-member;
member-function
public:
data-member;
data-member;
member-function
};
:
class_name List-of-objects;
على سبيل المثال :
- الكود:
class HUMAN
{
int HIEGHT,EYECOLOR,AGE; // data-member
char TYPE; // M: Man
// W: Women
public:
void input(); // member-function
void output();
};
:
HUMAN Steve, Jordan ;
في المثال أعلاه ، Steve و Jordanهما إعلانان لكائنان . يمكن الاحتفاظ بالأعضاء في أي من أوضاع إمكانية الوصول الثلاثة الخاصة والعامة والمحمية. يمكن للأعضاء في وضع الرؤية العامة public للفئة الوصول إلى كائنات الفئة بينما الأعضاء في وضع إمكانية الوصول الخاصة private لا يمكنهم الوصول إلى كائنات الفئة. يمكن الوصول إليها فقط داخل الفئة للدوال الأعضاء في الفئة .
ملاحظة: سيتم شرح الأعضاء المحميين Protected members لاحقًا في الدرس الثانى بعنوان "الميراث" ‘Inheritance’ .
يوضح البرنامج التالى استخدام الفئات والكائنات :
- الكود:
Program 1.1
/***********************************************************************
Program 1(1).cpp
Explaining the concept of classes and objects
***********************************************************************/
// Header files
# include <iostream.h>
# include <stdio.h>
// Declration of class hospital
class hospital
{
private:
int patientno,wardno; //private data members
char patient_name[20];
public:
void register_patient(); //public member function prototype
void showstatus() //public member function declaration
{
cout<<patientno<<":"<<patient_name<<":"<<wardno<<endl;
}
}; //semicolon is a must
/***********************************************************************
Name: register_patient
Class: hospital
Purpose: Input patient information
***********************************************************************/
void hospital::register_patient()
{
cout<<"patient no ?";
cin>>patientno;
cout<<"name ?";
gets(patient_name);
cout<<"Ward no ?";
cin>>wardno;
}
// Main function
void main()
{
hospital p1,p2;
p1.register_patient();
p2.register_patient();
p1.showstatus();
p2.showstatus();
}
// cin>>p1.wardno; ** not accessible as wardno is a private member
// cin>>p1.patientno; **not accessible as patientno is a private member
في المثال أعلاه ، يمكن للمرء أن يرى أن الفئة hospital يتم تعريفها بما يلى :
1- ثلاثة من أعضاء البيانات الخاصة patientno و wardno و patient_name ؛ و
2- دالتان عضوان عموميين register_patient() و showstatus() .
يمكن تعريف الدوال الأعضاء داخل الفئة وكذلك خارج الفئة كما هو موضح في المثال ، يتم تعريف الدالة العضو showstatus() داخل الفئة بينما يتم تعريف الدالة العضو register_patient() خارج الفئة باستخدام عامل دقة النطاق (: scope resolution operator مع اسم الفئة التي تنتمي إليها hospital::register_patient() . الشكل 1.4 يوضح استخدام عامل دقة النطاق. يمكن لكائنات الفئة استدعاء هاتين الدالتين بنفس الطريقة. عمومًا ، يتم تعريف الدوال ذات السطور المفردة داخل الفئة ، ويتم تعريف دوال المتعددة الأسطر والدوال لتي تحتوي على هياكل التحكم (if … else أو حلقات while ) خارج الفئة ليكون لها وضوح في فهم سلوك الفئة .
Figure 1.4: A function declared outside the class
ملاحظة: يعتمد حجم الكائن (بالبايت) على أعضاء البيانات الموجودين في الفئة التي ينتمي إليها. في المثال أعلاه ، يشغل الكائن p1 على 24 بايت.
أخطاء البرمجة الشائعة
• الإعلان عن الدوال الأعضاء خارج تعريفات الفئة دون نطاق عامل دقة المدى (: سيؤدي إلى خطأ.
• يجب أن تنتهي تعريفات الفئة بفاصلة منقوطة. تجاهل هذا سيؤدي إلى خطأ .
رد: البرمجة الموجهة للكائن Object-Oriented Programming
1.3.1 الدالة الصديقة Friend Function
يمكن فقط لدالة عضو من فئة ما الوصول إلى البيانات المعلنة بمحدد الوصول private في إعلان فئة نتيجة لذلك لا توجد فرصة لتغيير البيانات بشكل عرضي.
ومع ذلك ، هناك حالات يريد فيها المستخدم الوصول إلى بيانات كائن عن طريق دالة ليست دالة عضو في الفئة التي تنتمي إليها الكائنات. هذا ممكن عن طريق الإعلان عن الدالة كدالة صديقة للفئة . بناء الجملة لمثل هذه الدالة كما يلى :
1.3.2 الكائنات كوسائط Objects as arguments
قد يتم تمرير كائنات Objects مثل أي بيانات data أخرى كوسائط للدالة. يمكن استدعاءالدالة عن طريق استدعاء القيمة value أو يتم الاستدعاء عن طريق المرجع reference. في حالة الاستدعاء حسب القيمة ، لا يمكن أن تؤثر الدالة على تغييرات دائمة في البيانات التي يتم تلقيها كوسيط. ومع ذلك ، في الاستدعاء بالمرجع التغييرات التي أجريت على البيانات تكون دائمة. يشرح البرنامج 1.2 هذا المفهوم.
إخراج الشاشة :
في هذا البرنامج الفئة time تحتوى على hrs و mins كأعضاء "خاصة" private بها ، وبالتالي لا يمكن الوصول إليها من الدالة main . تحتوي الفئة time أيضًا على دوال عضو public يمكن من خلالها الوصول إلى هؤلاء الأعضاء "الخاصة" private .
عند تنفيذ هذا البرنامج ، يتم إنشاء الكائنات t1 و t2 و t3 في الفئة time . يتم استدعاء الدالة "gettime" للكائن t1 ويطلب من المستخدم إدخال الساعات والدقائق لهذا الكائن. يتم تخزين القيم التي أدخلها المستخدم '10' و '10' كقيمة هذه الكائنات للساعات والدقائق. بالمثل ، يتم استدعاء الدالة settime للكائن t2 ويتم تخزين القيمتين ‘3’ و ‘45’ كقيمة للكائن للساعات ‘hrs’ والدقائق ‘mins’ على التوالي. بالنسبة للكائن t3 ، يتم استدعاء الدالة sum حيث يتم تمرير الكائنات t1 و t2 كوسائط. قيم الأعضاء private members للكائن t3 وهى 'hrs' و 'minutes' هي مجموع قيم الأعضاء private members للكائن t1 وهى 10 و 10 وقيم الكائن t2 وهى 3 و 45 على التوالي.
يمكن فقط لدالة عضو من فئة ما الوصول إلى البيانات المعلنة بمحدد الوصول private في إعلان فئة نتيجة لذلك لا توجد فرصة لتغيير البيانات بشكل عرضي.
ومع ذلك ، هناك حالات يريد فيها المستخدم الوصول إلى بيانات كائن عن طريق دالة ليست دالة عضو في الفئة التي تنتمي إليها الكائنات. هذا ممكن عن طريق الإعلان عن الدالة كدالة صديقة للفئة . بناء الجملة لمثل هذه الدالة كما يلى :
- الكود:
{
private:
………………………… //private members
………………………...
public:
……………………… // public members
……………………...
friend data_type function_name(); // Declaration of friend function
};
1.3.2 الكائنات كوسائط Objects as arguments
قد يتم تمرير كائنات Objects مثل أي بيانات data أخرى كوسائط للدالة. يمكن استدعاءالدالة عن طريق استدعاء القيمة value أو يتم الاستدعاء عن طريق المرجع reference. في حالة الاستدعاء حسب القيمة ، لا يمكن أن تؤثر الدالة على تغييرات دائمة في البيانات التي يتم تلقيها كوسيط. ومع ذلك ، في الاستدعاء بالمرجع التغييرات التي أجريت على البيانات تكون دائمة. يشرح البرنامج 1.2 هذا المفهوم.
- الكود:
Program 1.2
/***********************************************************************
Program 2(2).cpp
The program displays objects being passed as arguments for class time and objects undergoing basic arithmetic operations.
***********************************************************************/
// Header Files
# include <iostream.h>
# include <conio.h>
class time
{
int hrs,mins;
public:
// Function to get time from the user
void gettime()
{
cout<<"Enter the hours !";
cin>>hrs;
cout<<" \nEnter the minutes !! ";
cin>>mins;
}
void settime (int h ,int m)
{
hrs=h; mins=m;
}
// Function to show time on the screen
void showtime()
{
cout<<hrs<<":"<<mins<<endl;
}
// Function to sum two objects of class time
void sum (time t1,time t2)
{
int minutes=t1.mins +t2.mins;
hrs = t1.hrs+t2.hrs +minutes/60;
mins=minutes%60;
}
};
// Main function
void main()
{
time t1,t2,t3;
t1.gettime(); // Call to function gettime
t2.settime(3,45); // Call to function settime
t3.sum(t1,t2); // Objects being passed as arguments
cout<<"\nt1=";
t1.showtime(); // Call to function showtime
cout<<"t2=";
t2.showtime();
cout<<"t3=";
t3.showtime();
}
إخراج الشاشة :
- الكود:
Enter the hours !10
Enter the minutes !! 10
t1=10:10
t2=3:45
t3=13:55
في هذا البرنامج الفئة time تحتوى على hrs و mins كأعضاء "خاصة" private بها ، وبالتالي لا يمكن الوصول إليها من الدالة main . تحتوي الفئة time أيضًا على دوال عضو public يمكن من خلالها الوصول إلى هؤلاء الأعضاء "الخاصة" private .
عند تنفيذ هذا البرنامج ، يتم إنشاء الكائنات t1 و t2 و t3 في الفئة time . يتم استدعاء الدالة "gettime" للكائن t1 ويطلب من المستخدم إدخال الساعات والدقائق لهذا الكائن. يتم تخزين القيم التي أدخلها المستخدم '10' و '10' كقيمة هذه الكائنات للساعات والدقائق. بالمثل ، يتم استدعاء الدالة settime للكائن t2 ويتم تخزين القيمتين ‘3’ و ‘45’ كقيمة للكائن للساعات ‘hrs’ والدقائق ‘mins’ على التوالي. بالنسبة للكائن t3 ، يتم استدعاء الدالة sum حيث يتم تمرير الكائنات t1 و t2 كوسائط. قيم الأعضاء private members للكائن t3 وهى 'hrs' و 'minutes' هي مجموع قيم الأعضاء private members للكائن t1 وهى 10 و 10 وقيم الكائن t2 وهى 3 و 45 على التوالي.
Samirrpic12- عدد المساهمات : 1
تاريخ التسجيل : 01/10/2021
مواضيع مماثلة
» أتمتة أنظمة التصنيع باستخدام المتحكمات المنطقية القابلة للبرمجة - الدرس الأول
» ما هي البرمجة ؟ What Is Programming?
» أسس البرمجة بلغة السى C Programming
» دروس البرمجة بلغة السى - 1 - مقدمة C Programming
» البرمجة التسلسلية فى الدائرة In-circuit Serial Programming (ICSP)
» ما هي البرمجة ؟ What Is Programming?
» أسس البرمجة بلغة السى C Programming
» دروس البرمجة بلغة السى - 1 - مقدمة C Programming
» البرمجة التسلسلية فى الدائرة In-circuit Serial Programming (ICSP)
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: البرمجة بلغة ++C مع ++Microsoft Visual C
صفحة 1 من اصل 1
صلاحيات هذا المنتدى:
لاتستطيع الرد على المواضيع في هذا المنتدى