الفئات والكائنات في ++C

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

وقد تحتاج خلال متابعتك هذه المقالات لأن ترجع بين الحين والأخر للمفاهيم التي أوردناها في المقالات السابقة .

مثال 1

يضم مثالنا التالي كائنين ينتميان لفئة بسيطة , ورغم ذلك , يقدم المثال الخصائص العامة للفئات في لغة السي ++ .

smallobj.cpp


 


// smallobj.cpp


// demonstrates a small, simple object


#include <iostream.h>


#include <conio.h>


 


class smallobj               // specify 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; }


   };


 


void 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();


   getche();


   }




تحتوي الفئة :



Class smallobj



علي بيان واحد , وعمليتين , هما الوحيدتان اللتان يمكن عن طريقهما التعامل مع البيان من خارج الفئة . إحدي الدالتين تخصص قيمة للبيان , والثانية لإظهاره .



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



Object-Oriented Programming in C   _Page_0243_Image_0001



























الفئات والكائنات



تذكر ما قلناه في المقالات السابقة من أن علاقة الكائن بفئته هي نفس علاقة المتغير بنوعه . ويقال إن الكائن هو "حادثة instance "من أحداث الفئة , كما أن سيارتي الشيفرليه موديل 1960 هي حادثة من أحداث السيارات .



وقد وصفت الفئة smallobj في صدر البرنامج , بحيث تضم بيانا ودالتين , إحداهما لتخصيص قيمة للبيان , والثانية لإظهاره علي الشاشة . وفي الدالة main() عرف كائنات منتميان للفئة ؛ هما s1, s2 . ثم خصصت قيمتان للكائنين وأظهرا علي الشاشة بإستخدام الدالتين المنتمين للفئة .



توصيف الفئة



يبدأ التوصيف (الإعلان) باستخدام الكلمة الحاكمة class , يتلوها الاسم المختار للفئة . وكما هو الحالة في الهياكل , يحتوي بلوك التوصيف قوسان حلزونيان , وينتهي بالفاصلة المنقوطة . (لا تنس قاعدة الفاصلة المنقوطة , تكون بعد التركيب المعرفة للبيانات , مثل الهياكل والفئات , ولا تكون بعد تراكيب التحكم , مثل الدوارات والدوال . )



البيانات المنتمية للفئة



تحتوي الفئة smallobj علي بيان واحد , هو البيان somedata , وهو بيان من نوع الأعداد الصحيحة int كما عرف علي أنه من النوع الخاص private , فهو غير متاح للتعامل إلا لدوال الفئة .



الدوال المنتمية للفئة



هي الدوال التي تعرف داخل الفئة . ( يطلق علي الدوال المنتمية للفئات في بعض اللغات مثل smalltalk مصطلح method وهي يعني حرفيا "طريقة" ويستخدم بعض كتاب السي ++ هذا المصطلح أيضا .) ولدينا في الفئة المبنية في المثال دالتان كما سبق بيانه .



ودوال الفئة هي المخولة أساس للعمل علي بيانات الفئة , كما أنها الوسيلة للتعامل مع الفئة من خارجها , ولذلك عرفت بأنها عامة public.



الخواص والعام



يحتوي تعريف الفئة علي كلمتين حاكمتين , private, public , فما معناهما ؟



من المبادئ الرئيسية في الأسلوب الكائني إخفاء البيانات data hiding بمعني أن البيانات في الفئة لا يمكن أن يتعامل معها دوال من خارج الفئة . وهو نوع من التحصين للبيانات ضد سوء الاستخدام . والطريقة للإخفاء هو بتعريف البيانات علي أنها "خاصة private" . أما ما يعرف من بيانات أو دوال علي أنه "عام public " فهو متاح للتعامل لكل الدوال ويبين الشكل هذا المفهوم .























Object-Oriented Programming in C   _Page_0245_Image_0001



شكل الخاص والعام



والجاري في الغالب أن تكون الدوال من النوع العام , والبيانات من النوع الخاص , وليس هذا بالقانون الجامد , فقد تقتضي الظروف الخروج عليه .



تعريف الكائنات المنتمية للفئة



بالنظر للبرنامج نجد أن تعريف الكائن المنتمي إلي الفئة يكون بالشكل التالي :



Smallobj s1 s2;



بالضبط كتعريف أي متغير عادي . وهنا فقط يحجز مكان في الذاكرة للكائنين المعرفتين



استدعاء الدوال المنتمية



يكون استدعاء الدوال المنتمية لكائن ما عن طريق ذكر اسم الكائن مرتبطا باسم الدالة بمؤثر النقطة dot operator السابق ذكره في موضوع الهياكل :



S1.setdata(1066);



S2.setdata(1776);



فاستدعاء مثل هذه الدوال دون ذكر الكائن المنتمية إليه ليس من المنطق في شئ فمؤثر النقطة هو وسيلتنا للتعامل مع دوال الفئة .



وبتطبيق الدالتين المذكورتين في المثال علي الكائنين s1, 12 يأخذ كل متغير somedata لكل كائن قيمته , ثم بتطبيق الدالتين :



S1.showdata();



S2.showdata();



يكون إظهار البيانين .



وهكذا لم يتم التعامل مع أي من متغيري الكائن smallobj إلا من خلال الدوال المنتمية للفئة , كما مبين بالشكل



Object-Oriented Programming in C   _Page_0248_Image_0001





















شكل كائنات منتميان للفئة smallobj



الرسائل



تسمي بعض اللغات مثل smalltalk استدعاء الدوال المنتمية رسالة message فينظر للأمر :



s.showdata();



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



مثال 2



نأخذ الأن مثالا أكثر تطورا , وهو صياغة البرنامج parts.cpp المعطي في موضوع الهياكل بأسلوب الكائنات .






objpart.cpp


 


// objpart.cpp


// widget part as an object


#include <iostream.h>


#include <conio.h>


 


class part               // specify an object


   {


   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 << "\nModel "  << modelnumber;


     cout << ", part "   << partnumber;


     cout << ", costs $" << cost;


     }


   };


 


void main()


   {


   part part1;                        // define object


                      //    of class part


   part1.setpart(6244, 373, 217.55);  // call member function


   part1.showpart();                  // call member function


   getche();


   }




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



مثال 3



نطور في المثال التالي برامج إظهار المسافة بالأقدام والبوصات , لنصوغها بالأسلوب الكائني .






englobj.cpp


 


// englobj.cpp


// objects using English measurements


#include <iostream.h>


#include <conio.h>


 


class Distance                    // English Distance class


   {


   private:


      int feet;


      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 << '\"'; }


   };


 


void main()


   {


   Distance dist1, dist2;         // define two lengths


 


   dist1.setdist(11, 6.25);       // set dist1


 


   dist2.getdist();               // get dist2 from user


 


                  // display lengths


   cout << "\ndist1 = ";  dist1.showdist();


   cout << "\ndist2 = ";  dist2.showdist();


   getche();


   }




وفي هذا المثال تضم الفئة distance بيانين feet, inches علي غرار ما كان في الهيكل المعطي في الفصل الخامس , ثم ثلاث دوال منتمية member functions للفئة ؛ setdist() المسئولة عن تخصيص قيم البيانين عن طريق البرنامج ,و getdist() التي بها يدخل قيم لهما عن طريق المستخدم , و showdist() لإظهار قيمهما علي الشاشة .

التسميات: