/Java Programming: Let's Master 7/i

Java Programming: Let's Master 7/i

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

احنا في الجزء ده هنتكلم علي حاجات كانت مبهمة قبل كده زي يعني ايه  class , object؟  ، وهنتعرف علي معناهم وكل حاجة تخصهم بإذن الله..

7.2. Defining Classes for Objects

واول تعريف لينا هو يعني ايه object ؟ ، بيقول لينا ان الـ object عبارة عن شيء موجود في البيئة المحيطة بيه ، يعني لو قولنا امثلة هنقول الدايرة او ال button او حتي القرض ممكن نعتبرهم  objects ، اي object لو جينا نعرف مكوناته هنلاقيه بيتكون من :

1- ال state ودي بتوصف ال object وبيقوم بالمهمة دي ال data fields او المتغيرات العادية بقيمهم الحالية

2- ال behavior وهو سلوك الobject ده يعني بيعمل ايه وبيقوم بالمهمة دي مجموعة من ال methods .

ومعني اني بستدعي ميثود من object ده معناه اني عاوز الobject ده يقوم بوظيفة معينة.

مثال : الobject بتاع الدايرة فيه متغير اسمه radius وده بيوصف الدايرة وممكن ال behavior يكون حساب مساحة الدايرة دي عن طريق استدعاء الميثود اللي اسمها ()getArea

نيجي لتعريف تاني وهو يعني ايه class ؟ ، بيقول ان الكلاس ببساطة عبارة عن وعاء لل objects اللي من نفس النوع ، “وعاء” بمعني اني بعرف فيه المتغيرات والميثودس الخاصة بالobjects . وبيقول كمان ان الobject بيبقي جزء من الclass وممكن نعمل اكتر من object من نفس الكلاس وبيبقي اسمه instance وكلمة object و instance تقريبا بنفس المعني. وبيقول ان العلاقة بين ال class وال object تقريبا زي فطيرة التفاح وطريقة عمل فطيرة التفاح ممكن اعمل اكتر من فطيرة تفاح بإستخدام الوصفة الواحدة.

كلاس الجافا بيستخدم المتغيرات في تعريف ال data fields والميثودس في تعريف ال behavior وكمان الكلاس بيعمل ميثود من نوع خاص اسمها constructor الميثود دي بتتنفذ اول مابعمل object من الكلاس ده. بيقول ان الconstructor ممكن تقوم بأي وظيفة ولكن في الغالب بتقوم بإعطاء المتغيرات التابعة لل objects قيم مبدئية زي كده:

كلاس circle ده مختلف شوية عن الشكل اللي احنا متعودينه اكيد طبعا اول شيء هنلاحظه انه مش فيه ميثود ال main وده معناه انه مش بقدر اعمل له run ولكن هو بس معمول علشان عن طريقه اقدر اعمل objects واستعملهم والكلاس اللي هيبقي فيه ميثود ال main هيبقي اسمه الكلاس الأساسي . لو حبينا نعمل للكلاس بتاعنا تصميم معترف بيه دوليا يبقي هنعمله مايسمي بال UML CLASS DIAGRAM وبيبقي شكله عامل كده:

وفيه المتغيرات بتتعرف فيه بالطريقة دي :

والconstructor بيتعمل كده :

والميثود بتتعرف كده :

7.3. Constructors

اول معلومة لازم نعرفها عن ال constructor هي انه بيبقي اسمه نفس اسم الكلاس اللي هو فيه وزيه زي كل الميثودس ممكن اعمل له overload (يعني اعمل اكتر من constructor بنفس الأسم ولكن بيبقوا مختلفين في باقي التعريف) وده طبعا بيسهل إعطاء المتغيرات قيم مبدئية جدا. لما نحب نعمل object من اي كلاس بننادي ال constructor بتاع الكلاس ده بإستخدام كلمة محفوظة في اللغة وهي كلمة new زي كده :

مثلا لما بنقول ()new circle كده بنعمل object من كلاس ال circle بإستخدام اول constructor في الكلاس ولو قولنا (new circle(5 هنبقي بنعمل object من نفس الكلاس ولكن بإستخدام ال constructor التاني اللي متعرف في نفس الكلاس .
الكلاس عموما بيخلق اوتوماتك constructor مش بياخد اي argument وبيكون اسم ال constructor في الحالة دي no-arg constructor او no-argument constructor .
الكلاس ممكن يتعمل بدون اي constructor وفي الحالة دي بيتخلق constructor فاضي وبيكون موجود ضمنيا في الكلاس وبيبقي اسمه default constructor وبيتعمل فقط في حالة انه متمش تعريف constructor بوضوح في الكلاس.
ملحوظة :
ال constructor هو ميثود من نوع خاص وفرقه عن الميثود العادية :
• الconstructor لازم يكون اسمه مطابق لأسم الكلاس اللي اتخلق فيه.
• الconstructors مش ليها return type ولا حتي void .
• لما بنادي اي constructor باستخدم كلمة new وبيلعب ال constructor دور تعريف المتغيرات وإعطائم قيمة مبدئية .
ملحوظة ::
من الأخطاء الشهيرة كتابة void مع ال constructor زي كده:

وفي الحالة دي ()Circle هتبقي ميثود عادية مش constructor .

7.4. Accessing Objects via Reference Variables

 

طيب دلوقتي احنا عملنا ال object ازاي اتعامل معاه بقي؟

7.4.1. Reference Variables and Reference Types

 

علشان اتعامل مع اي object بتعامل معاه عن طريق مايعرف بال reference variable بمعني اني بعرف ال object علي هيئة متغير زي كده :

والكلاس بيحدد نوع ال object مثلا كلاس الcircle لو عرفت منه object هيبقي بالمنظر ده :

عن طريق المتغير myCircle بنعمل مرجع او reference ل object من الكلاس Circle وبعد كده هنكمل تعريف الobject وهبعت المرجع او ال reference بتاعه للمتغير myCirle كده:

ممكن في جملة واحدة اعرف object من كلاس معين وابعت الreference بتاعه لمتغير معين زي كده :

ومثال علي الكلام ده :

المتغير myCircle بيحتوي علي reference او مرجع للobject اللي من الكلاس Circle .
ملحوظة ::
فيق فرق بين اني اقول ان المتغير myCircle بيحتوي علي مرجع لobject من الكلاس Circle وبين اني اقول ان المتغير myCircle هو عبارة عن object من الكلاس Circle ولكن لتسهيل الأمور هنقول ان myCircle هو object من كلاس Circle وطبعا لو انطلب توضيح الفرق لازم نكون عارفينه.

7.4.2. Accessing an Object’s Data and Methods

دلوقتي احنا عملنا object عاوزين نتعامل مع المتغيرات والميثودس الخاصة بيه :
1- لو عاوزين نتعامل مع data field هنناديه بالطريقة دي : objectRefVar.dataField
2- لو عاوزين نتعامل مع ميثود هناديها بالطريقة دي : objectRefVar.method(arguments)
يعني مثلا myCircle.radius يبقي هنتعامل مع الradius بتاع الobject اللي اسمه myCircle ولو قولنا ()myCircle.getArea يبقي هننفذ الميثود اللي اسمها ()getArea علي ال object اللي اسمه myCircle .
ملحوظة ::
في بعض الأحيان مش لازم اعرف متغير علشان يبقي فيه مرجع او reference للobject ولكن ممكن اعمل ال object علطول زي كده :

او

وفي الحالة دي ال object بيبقي اسمه anonymous object .

7.4.3. Example: Declaring Classes and Creating Objects

وده مثال علي الكلام اللي فات :

لو جينا نحلل البرنامج ده هنلاقي عندنا اتنين كلاس :
الأول TestCircle1 وده الكلاس الأساسي ومهمته هو عمل Test علي الكلاس التاني Circle . ممكن احط الكلاسين في نفس الملف ولكن لازم واحد فيهم بس هو اللي يبقي public وهو الكلاس الأساسي اللي فيه ميثود ال main وفي الحالة دي بنسمي الملف بأسم الكلاس الأساسي يعني هيبقي اسم الملف TestCircle1.java . في الكلاس الأساسي وجوه ميثود الmain عملت اتنين objects اول واحد عن طريق ال constructor اللي بياخد قيمة وهنديله قيمة 5.0 والobject التاني هسيبه بالقيمة الإفتراضية اللي هي 1.0 .
طبعا الأتنين object دول بيختلفوا في قيم الداتا اللي فيهم ولكن بيشتركوا مع بعض في نفس الميثودس وبكده ممكن احسب لكل object فيهم المساحة . ولما حبينا ننفذ ميثود ()getArea مع كل object ناديناها بأسم الobject .
فيه اكتر من طريقة لكتابة برامج الجافا مثلا ممكن دمج اكتر من كلاس في ملف واحد زي كده :

طبعا طالما الكلاس فيه ميثود ال main يبقي هيشتغل عادي جدا وال object اللي تم تخليقه هيبقي من كلاس Circle1 .
ملحوظة ::
لما جينا نتعامل مع الميثودس قولنا لما جينا نتعامل مع كلاس Math اني بنادي اي ميثودي فيه بالطريقة دي Math.pow(2,3) كنا بنستخدم اسم الكلاس وبعدين اسم الميثود بس ده كان علشان كل الميثودس اللي موجودة في كلاس ال Math من نوع static وهنشرح يعني ايه static قدام ولكن هنا في مثالنا الميثود مش من نوع static او non-static يعني علشان اناديها لازم يكون عن طريق object فقط لا غير.

Reference Data Fields and the null Value

بيقولنا ان المتغيرات في البرنامج ممكن يكونوا reference type يعني مش من الأنواع المحفوظة في اللغة زي الint , double  زي كده :

لو المتغير مش بيحمل reference لأي object في الحالة دي بحمل قيمة خاصة في الجافا اسمها null واللي عاملة زي true , false ولكن دول بيبقول قيم Boolean ولكن null بتحمل reference .
– والقيمة null في حالة الobject بتبقي بـnull
– وفي حالة المتغيرات العددية بتبقي بـ 0
– وفي حالة المتغير ال Boolean بتبقي بـ false
– وفي حالة الحروف بتبقي بـ \u0000
ملحوظة ::
قبل التعامل مع اي متغير لابد من إعطاءة قيمة مبدئية او افتراضية اولا يعني كود زي ده هيطلع خطأ :

ملحوظة ::
NullPointerException ده خطأ شائع بيطلع في حالة استدعاء وتنفيذ ميثود معتمدة علي متغير يحمل قيمة null

7.4.5.Differences Between Variables of Primitive Types and Reference Types

كل متغير عندنا عبارة عن موقع في الميموري بيحتفظ بقيمة معينة ولما بنعرف متغير بعرف ال compiler نوع القيم اللي المتغير ده يقدر يحتفظ بيها. لو كان المتغير نوع من الأنواع المحفوظة هتبقي قيمته من نفس نوعه , وفي حالة لو كان المتغير بيحمل reference لobject هتبقي قيمته هي Reference لمكان ال object ده في الميموري زي كده: هنلاقي ان قيمة المتغير اللي اسمه i واللي من نوع int هتبقي int value =1 والobject اللي اسمه c ومن نوع Circle هنلاقيه بيشور او بيحمل Reference لمكان الobject Circle في الميموري:

لما باجي اقول i = j اللي بيحصل ان القيمة اللي في الj بتتنسخ في الi طيب ده في حالة المتغيرات العادية , في حالة المتغيرات اللي بتحمل reference لobject لو قولنا c1=c2 ده معناه ان قيمة ال Reference اللي في c2 هتتنسخ في c1 وهما الأتنين هيشوروا او هيحملوا نفس ال reference:

ملحوظة ::
لما حطينا قيمة ال reference بتاع الobject اللي اسمه c2 في الobject اللي اسمه c1 دلوقتي c1 قيمته القديمة اصبحت ملهاش لازمة وغير صالحة للإستخدام وده مايعرف بال garbage والجافا بتعرف القيم اللي من النوع ده واوتوماتك بتفضي المساحة اللي بتاخدها من الميموري وده مايعرف بال garbage collection.

7.5. Using Classes from the Java Library

احنا قبل كده عملنا كلاس وخلقنا فيه objects بس في البرامج ممكن نحتاج نتعامل مع كلاسات جاهزة في اللغة والسكشن ده بيدي امثلة علي بعض الكلاسات الجاهزة في الجافا .

7.5.1. The Date Class

احنا قبل كده اتعلمنا ازاي نقري الوقت بإستخدام ميثود ()System.currentTimeMillis دلوقتي هنقرأ الوقت ولكن بإستخدام كلاس جاهز اسمه Date وموجود في package اسمها java.util

طبعا زي ماحنا شايفين اول حاجة ال constructors علشان اخلق object او instance من الكلاس ده وبعد كده هنلاقي ميثود  ()getTime واللي بترجع الوقت الحالي وميثود ()toString  واللي بترجع الوقت علي هيئة string زي كده:

هتعرض الناتج بالمنظر ده:

7.5.2. The Random Class

قبل كده برده استخدمنا ميثود ()Math.random واللي بترجع قيمة بين 0-1.0 . هنلاقي هنا كلاس جاهز فيه امكانيات اعلي واحسن وهو كلاس Random واللي موجود في package اسمها java.util:

نفس الكلام اللي قولناه اول حاجة طبعا الconstructors وبعد كده هنلاقي مجموعة من الميثودس المفيدة جدا في حالة كل نوع من انواع المتغيرات.

لحد هنا نكون تقريبا اتعرفنا إلى حد ما على المصطلحات الجديدة علينا زي كلاس وأوبجكت وكيفية اشتقاق اوبجكت من كلاس عن طريق الـ constructor ومقدمة عن لغة الـ UML وطريقة تمثيل الكلاسات بها.. وان شاء الله معادنا المرة الجاية نكمل في الـOOP  ونكمل شابتر 7.

It’s totally free to share

Thanks CAT Reloaded

Thanks CATaZine

Om4rezz