|
| قسم لغات البرمجة php java c++ جافا Visual Basic فيجوال بيسك c# Delphi دلفي API PERL HTML و TML JavaScript ASP XML Oracle اوركال MySql sql server Access |
|
|
| F.Abdelaziz |
| مشاهدة ملفه الشخصي |
| زيارة موقع F.Abdelaziz المفضل |
| البحث عن كافة المشاركات المكتوبة بواسطة F.Abdelaziz |
| اعلانات |
|
||||||
|
الدرس الثانى الكائنات والفئات 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++ ، لكن من المفيد أن نأخذه في الاعتبار عند مناقشتنا الدوال الأعضاء. الحديث عن الرسائل يؤكد أن الكائنات كيانات منفصلة وأننا نتواصل معها من خلال استدعاء الدوال الأعضاء. بالإشارة إلى التشابه مع تنظيم الشركة في الدرس الأول ، من المفضل إرسال رسالة إلى السكرتير في قسم المبيعات لطلب قائمة بالمنتجات التي تباع في منطقة التوزيع الجنوبية الغربية. |
| F.Abdelaziz |
| مشاهدة ملفه الشخصي |
| زيارة موقع F.Abdelaziz المفضل |
| البحث عن كافة المشاركات المكتوبة بواسطة F.Abdelaziz |
| اعلانات اضافية ( قم بتسجيل الدخول لاخفائها ) | |
|
|
|
||||||
|
كائنات C++ ككائنات فعلية (طبيعية) C++ Objects as Physical Objects في العديد من مواقف البرمجة ، تمثل الكائنات الموجودة في البرامج كائنات مادية (طبيعية) : أشياء يمكن الشعور بها أو رؤيتها. توفر هذه الحالات أمثلة حية على التطابق (التشابه) البرنامج والعالم الحقيقي. سننظر في حالة من هذه الحالات : أجزاء القطعة 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 . |
|
||||||
|
كائنات C++ كأنواع بيانات C++ Objects as Data Types في ما يلي نوع آخر من الكائنات التي يمكن أن تمثلها عناصر 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 يوضح المثال 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 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 بايت. أخطاء البرمجة الشائعة • الإعلان عن الدوال الأعضاء خارج تعريفات الفئة دون نطاق عامل دقة المدى (: سيؤدي إلى خطأ.• يجب أن تنتهي تعريفات الفئة بفاصلة منقوطة. تجاهل هذا سيؤدي إلى خطأ . |
|
||||||
|
1.3.1 الدالة الصديقة Friend Function يمكن فقط لدالة عضو من فئة ما الوصول إلى البيانات المعلنة بمحدد الوصول 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 على التوالي. |
|
جميع الحقوق محفوظة 2026
|


