عرض مشاركة واحدة
منتديات طلاب وطالبات جامعة الملك عبد العزيز منتديات طلاب وطالبات جامعة الملك عبد العزيز
  #1  
قديم 12-03-2010, 01:37 AM
الصورة الرمزية Mr.Ahmad

Mr.Ahmad Mr.Ahmad غير متواجد حالياً

عضو هيئة تدريس

 
تاريخ التسجيل: Jul 2008
الكلية: كلية الحاسبات وتقنية المعلومات
التخصص: IT
نوع الدراسة: عضو هيئة تدريس
المستوى: متخرج
البلد: جــــدة
الجنس: ذكر
المشاركات: 2,477
Skaau.com (11) [شرح][ CPCS 203 - برمجة 2 ] أفهم عمل الكلمة الأساسية new عند إنشاء كائن (Object) !


بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته


---------------------------------------------------------------------------
* مــا شاء الله تبارك الله *
الحمد لله عدد ما خلق , الحمد لله ملء ما خلق , الحمد لله عدد ما في السموات وما في الأرض , الحمد لله عدد ما أحصى كتابه ، والحمد لله على ما أحصى كتابه ، والحمد لله عدد كل شيء والحمد لله ملء كل شيء .
اللهم صل على محمد وعلى آل محمد كما صليت على إبراهيم وعلى آل إبراهيم إنك حميد مجيد . اللهم بارك على محمد وعلى آل محمد كما باركت على إبراهيم وعلى آل إبراهيم إنك حميد مجيد.
لا إله إلا الله وحده لا شريك له الملك وله الحمد وهو على كل شيء قدير .
سبحـــــــان الله وبحمده ... سبحــان الله العظيم
---------------------------------------------------------------------------
[شرح][ CPCS 203 - برمجة 2 ] أفهم عمل الكلمة الأساسية new عند إنشاء كائن (Object) !

الدرس السابق :

تعلمنا في الشرح الأول ما هي الفئة (Class) والكائنات (Objects) والفرق بينهما ، فعرفنا البشر (الناس) كفئة (class) و كل إنسان على وجه الأرض يعتبر كائن (Object) من فئة البشر . هذا كان مختصر الدرس السابق .
في هذا الدرس الخفيف , سنتعلم ما هي الكلمة new التي نستخدمها عند إنشاء كائن من فئة , ولماذا نستخدمها وكيف تأثيرها على الذاكرة , لنبدأ الدرس أولاً باسم الله الرحمن الرحيم . ثانياً , للنظر إلى هذا الكود :




في هذا الكود عرفنا متغيرين الأول نوعه رقم Integer والثاني نوعه رقم Double , في هذه الحالة سيحجز المُصرف (المترجم) كتلة (مكان) من الذاكرة كبيرة كافية لتخزين المتغير الأول والثاني . والقيمة لكلا المتغيرين تُنسخ إلى كتلة الذاكرة تلك المحجوز لهما . أنظر إلى الصورة التوضيحية التالية التي توضح عمل الكود السابق في الذاكرة :




كما شاهدنا في الصورة التوضيحية , نرى أن المتغيرات السابقة حجزت كتلة من الذاكرة كبيرة وكافية لتخزين نوعيهما , فالمتغير ذو النوع int حجز في الذاكرة كتلة 32 بت (4 بايت) فهذه الكتلة المحجوزة هي أقصى قيمة ممكنة يستطيع المتغير ذو النوع int تخزينها , ونفس الأمر في المتغير ذو النوع double فسيحجز كتلة 64 بت (8 بايت) وهي أقصى قيمة ممكنة أن يخزنها هذا النوع .

هذه الأنواع البدائية التي يمكن تعريفها وإسناد قيمتها مباشرة كما في int وfloat و double و غيرها من أنواع المتغيرات المعروفة لدينا , تُسمى "أنواع قيمية" أو "أنواع مباشرة" لأنها كما أسلفنا تُخزن القيم مباشرة .
ولكن الأمر يختلف مع الكائنات (Objects) , شاهد الكود التالي :




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

شاهد كيف يتم تنفيذ الكود السابق في الذاكرة :




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

يتم تخزين الأنواع القيمية (مثل int و Boolean وغيرها) في المكدس مباشرة (كما رأينا في الصورة التوضيحية الأولى) , أما الأنواع المرجعية (هي الكائنات Objects) فأنه يتم حجز قطعة كبيرة كافية لتخزين مرجع (مؤشر) ولكن هذا المرجع غير ممهد (أي أنه فارغ) , ثم عند استعمال الكلمة الأساسية new يتم حجز قطعة أخرى من الذاكرة التكويمية كبيرة كافية لتخزين كائن (الكائن هنا في المثال هو MyClass) . يشتغل مُشيد MyClass() - (المُشيدات Constructor مفهوم آخر سيتم الحديث عنه في درس لاحق إن شاء الله) – لتحويل هذه الذاكرة التكويمية الخام إلى كائن MyClass . ثم بعد ذلك يتم تخزين مرجع إلى هذا الكائن MyClass في المتغير c .


ملاحظة : رأيت كثير من الطلاب تختلط عليهم كلمة instance ، وبالتالي يسألوا ما الفرق بين Class و Objects و instance ؟!
بخصوص الفرق ومفهوم الـ Class و الـ Objects شرحناه في الدرس السابق .
وأما بخصوص كلمة instance فهذه كلمة إنجليزية عادية معناها "مثيل" , اُستخدمت في الكتاب أو شرائح الدروس لتخبرنا أننا عندما نكتب الكلمة الأساسية new ثم اسم الفئة فأنه سيتم إنشاء مثيل للفئة , ومثيل الفئة هو الكائن (Object) , أي أن الكائن هو مثيل لفئته (نسخة طبق الأصل) .


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

مثال تطبيقي :
عرفنا في الكود التالي فئة اسمها Student وبها خاصية نوعها سلسلة نصية اسمها Name لحفظ اسم الطالب بداخلها . ثم بعد ذلك في الطريقة الرئيسية للبرنامج عرفنا متغير واحد وثلاثة كائنات من فئة Student:




نتيجة الكود السابق :




لعلك لاحظت أننا استخدمنا الكلمة الأساسية new على s1 و s2 , أما s3 فتم تسويته بـ s1 . لقد رأيت عند طباعة ناتج أن s3 يساوي s1 وكأنهم كائن واحد له اسمين مختلفين ؟! نعم هذا صحيح , s3 يؤشر على الكائن الذي يؤشر عليه s1 , شاهد ماذا يحدث في الذاكرة :




ملاحظة : لو كان لدينا أحد الأنواع القيمية , وفعلنا التالي :

كود:
int i = 4; int x = i; i++;
في السطر الأول والثاني قيمة i سيتم نسخها - وليس التأشير إليها كما في الأنواع المرجعية - إلى قيمة x .
وفي السطر الثالث سيتم زيادة i بواحد .
نتيجة الكود السابق :
i = 5
x = 4


بهذا القدر نكتفي , ومختصر الشرح :
* كل الأنواع القيمية تُنشأ في المكدس , وكل الأنواع المرجعية (الكائنات) تُنشأ في الذاكرة التكويمية .

* عند تعريف كائن كـ (ClassName objectName) – بحيث نستبدل ClassName باسم الفئة و objectName بأي اسم نريده للكائن – فإننا في الأصل عرفنا مرجع (مؤشر) لكائن نوعه ClassName .

* عند استخدام الكلمة الأساسية new كـ ( () ClassName objectName = new ClassName) فإننا أنشانا كائن جديد من نوع ClassName وجعلنا objectName يؤشر عليه .

---------------------------------------------------------------------------

أعتذر على الإطالة ...
و لا تنسونا من دعائكم .
وتمنياتي لي و لكم بالتوفيق,,,

 


توقيع Mr.Ahmad  

سبحان الله وبحمد ,,, سبحان الله العظيم
الحمد لله كما ينبغي لجلال وجهه وعظيم سلطانه .
اللهم صل على محمد وعلى آل محمد كما صليت على إبراهيم وعلى آل إبراهيم إنك حميد مجيد . اللهم بارك على محمد وعلى آل محمد كما باركت على إبراهيم وعلى آل إبراهيم إنك حميد مجيد.

 


التعديل الأخير تم بواسطة Mr.Ahmad ; 12-03-2010 الساعة 01:49 AM.
رد مع اقتباس