0

آموزش برنامه نویسی جاوا

 
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش زبان برنامه نویسی جاوا - قسمت ۳۲: معرفی وارثت در زبان برنامه نویسی جاوا



در حقیقت در برنامه نویسی گاهی برنامه نویسان مجبور هستند Object های متفاوتی ایجاد کنند. در همین حین ممکن است برخی از Object ها خصوصیاتشان مشابه برخی دیگر Object ها باشد. حال اگر برنامه نویس بخواهد تک تک این Object ها را ایجاد کند و خصوصیات یکسانشان را نیز برای هر کدام تعریف کند، اگر در حین نوشتن پروژه بخواهد تا تغییری در برخی خصوصیات Object ها اعمال کند، مجبور است تا کلیه Object ها را بازنویسی کند و در همین جا است که یکی از بهترین ویژگی های زبان برنامه نویسی جاوا که یک زبان برنامه نویسی شئ گرا است را می تواند مورد استفاده قرار داده تا دیگر مجبور نباشد در صورت بروز یک تغییر، کل خصوصیات و یا رفتارهای Object های ایجاد شده را بازنویسی کند. در حقیقت این ویژگی Inheritance یا "به ارث بردن" نام دارد.

به طور خلاصه اگر برنامه نویس بخواهد یک Object ایجاد کند که تمامی و یا برخی از ویژگی های یک Object دیگر را داشته باشد می تواند از قابلیت ارث بری در زبان برنامه نویسی جاوا استفاده کند. در ضمن اگر برنامه نویس بخواهد تا یک Object کلیه ی ویژگی های Object دیگری را به ارث برد به جز یک ویژگی که می بایست تغییر کند، این کار از طریق وراثت باز هم امکان پذیر است. از سوی دیگر وراثت سلسله مراتبی نیز امکان پذیر است. فرض کنیم که ما سه Object داریم به طوریکه Object شماره دو از Object شماره یک ارث بری می کند و Object شماره سه از Object شماره دو. در واقع Object شماره سه نه تنها از ویژگی های Object شماره دو برخوردار خواهد بود، بلکه از آنجا که Object شماره دو از Object شماره یک ارث بری می کند، Object شماره سه ویژگی های Object شماره یک را نیز در بر خواهد داشت. در این مثال Object شماره یک به عنوان Superclass یا "کلاس اصلی" تلقی می شود و Object های شماره دو و سه به عنوان Subclass یا "کلاس زیرشاخه" تلقی خواهند شد. جالب است بدانیم که در مثال فوق اگرچه که Object شماره دو برای Object شماره یک به عنوان یک Subclass تلقی می شود اما این در حالی است که برای Object شماره سه به عنوان یک Superclass مد نظر قرار داده می شود. این رابطه به خوبی در تصویر زیر قابل مشاهده است:

920522-j32-IMAGE 1.jpg

حال برای آنکه درک بهتری از وارثت در زبان برنامه نویسی جاوا داشته باشیم مثالی از دنیای واقعی زده و سپس آن را به یک پروژه شیئ گرایی تبدیل می کنیم. پدر بزرگ خود را در نظر بگیریم که مثلاً دارای یکسری خصوصیات از این قرار است:


920522-j32-IMAGE 2.jpg

در واقع برخی از این خصوصیات در ژن ایشان غالب بوده و به فرزندشان که پدرمان باشد انتقال پیدا کرده است. در حقیقت از موارد فوق، خصوصیاتی که پدرمان از پدر بزرگمان به ارث برده عبارتند از:


920522-j32-IMAGE 3.jpg

همانطور که در جدول فوق مشاهده می شود پدرمان مورد 4 را از پدر بزرگ به ارث نبرده است. به عبارت دیگر ایشان به جای اینکه عصبانیت را از پدر خود به ارث برده باشد، در عوض فرد خوش اخلاقی است. از سوی دیگر در مورد 5 هم پدر خلاقیتشان به اندازه پدر بزرگ نیست. به عبارت دیگر ایشان بسیار خلاق نیستند بلکه خلاق هستند. به این اتفاق در زبان برنامه نویسی جاوا Override یا "رونویسی" می گویند. به عبارت ساده تر، زمانیکه ما بخواهیم که یک کلاس Subclass تعدادی از ویژگی های کلاس Superclass را به ارث نبرد، می بایست آن ویژگی مد نظر را Override کرد. علاوه بر این به خاطر داشته باشیم که هر موقع یک ویژگی هم در کلاس Superclass موجود باشد و هم در کلاس Subclass ، در این مواقع Compiler ویژگی موجود در Subclass را مد نظر قرار خواهد داد. در نهایت به خاطر داشته باشیم که برای Override کردن اجازه نداریم تا Modifier متد و یا تعداد و یا نوع پارامترهای آن را تغییر دهیم(البته می توانیم نام پارامترهای آن را تغییر دهیم).

علاوه بر مواردی که پدر از پدر خویش به ارث برده، ایشان دارای دو خصیصه دیگر نیز می باشند که مخصوص به خودشان است که این دو خصیصه در موارد 8 و 9 گنجانده شده اند. در واقع میزان سواد ایشان در سطح لیسانس بوده و سطح مطالعه ایشان زیاد می باشد. اکنون ببینیم که پسر چه ویژگی هایی را از پدر به ارث برده است:


920522-j32-IMAGE 4.jpg

همانطور که در جدول فوق مشاهده می شود، پسر در مورد 1 برخلاف پدرش و پدر بزرگش قد بلند است، پسر در مورد 3 برخلاف پدرش و پدر بزرگش طاس نیست، پسر در مورد 4 برخلاف پدرش که فرد خوش اخلاقی بود، عصبانیت را مجددا از پدر بزرگ خود به ارث برده است. در مورد 8 پسر بر خلاف پدرش تحصیلاتش را ادامه داده و فوق لیسانس دارد. در مورد 9 برخلاف پدر که زیاد مطالعه می کند، پسر خیلی زیاد مطالعه می کند. به منظور درک بهتر این روابط از نمودار زیر استفاده می کنیم:


920522-j32-IMAGE 5.jpg

همانطور که در تصویر فوق نشان داده شده است، پدر بزرگ با رنگ قرمز، پدر با رنگ سبز و پسر با رنگ آبی مشخص شده اند. در مستطیل مشکی رنگ خصوصیاتی نشان داده شده است که بین هر سه نسل مشترک می باشند. سپس خصوصیاتی که خاص هر فرد است در بالای سرش مشخص شده است. در قسمت آموزشی سی و سوم، از خصوصیات مابین پدر بزرگ، پدر و پسر استفاده کرده و پروژه ای جدید می نویسیم که در آن کلیه وراثت ها مورد استفاده قرار گرفته باشند.

چهارشنبه 2 بهمن 1392  11:46 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۳۳: به کارگیری وراثت در جاوا در قالب پروژه شجره نامه


پس از آشنایی با مفهوم وراثت در زبان برنامه نویسی جاوا در قسمت سی و دوم در قالب مثال پدر بزرگ، پدر و پسر، اکنون قصد داریم تا با نوشتن پروژه ای مرتبط، این ویژگی منحصر به فرد زبان برنامه نویسی جاوا را مورد بررسی قرار دهیم. برای این منظور پروژه ای تحت عنوان 33rd Session به معنی "جلسه سی و سوم" ایجاد کرده و سه کلاس مجزا تحت عناوین Grandfather و Father و Son به معانی به ترتیب "پدر بزرگ، پدر و پسر" ایجاد می کنیم. برای ساخت این سه کلاس نیازی نیست تا گزینه public static void main را تیک بزنیم چرا که این کلاس ها به منزله نقطه شروع برنامه ما نخواهند بود. سپس کلاسی تحت عنوان ActionClass به معنی"کلاس اجرایی" ایجاد کرده و از آنجا که می خواهیم این کلاس به منزله کلاسی باشد که برنامه ما از طریق آن آغاز می شود، پس گزینه public static void main را برای آن در حین ساخت تیک دار می کنیم و به ادامه مطلب می رویم!

اکنون پروژه ما می بایست به شکل زیر تکمیل شده باشد:

920526-j33-IMAGE 1.jpg

برای شروع برنامه نویسی این پروژه، کار خود را از کلاس پدر بزرگ شروع می کنیم. پس از باز کردن این کلاس، کدی مشابه کد زیر خواهیم داشت:


  1. public class Grandfather {
  2.  
  3. }

اکنون نیاز داریم تا متدهایی به منظور ذخیره سازی خصوصیات پدر بزرگ در این کلاس ایجاد کنیم. برای همین منظور، کد فوق را به صورت زیر تکمیل می کنیم:

  1. public class Grandfather {
  2.  
  3. public void showGrandfatherHeight() {
  4. String height = "Short";
  5. System.out.println(height);
  6. }
  7. public void showGrandfatherSkinColor() {
  8. String skinColor = "Bright";
  9. System.out.println(skinColor);
  10. }
  11. public void showGrandfatherBoldness() {
  12. String boldness = "Bold";
  13. System.out.println(boldness);
  14. }
  15. public void showGrandfatherBehavior() {
  16. String behavior = "Angry";
  17. System.out.println(behavior);
  18. }
  19. public void showGrandfatherCreativity() {
  20. String creativity = "Very Creative";
  21. System.out.println(creativity);
  22. }
  23. public void showGrandfatherActivity() {
  24. String activity = "Very Active";
  25. System.out.println(activity);
  26. }
  27. public void showGrandfatherNationality() {
  28. String nationality = "Iranian";
  29. System.out.println(nationality);
  30. }
  31.  
  32. }

همانطور که مشاهده می شود Modifier متدهای خود را public قرار داده ایم چرا که می خواهیم در مابقی کلاس ها هم در دسترس باشند(در آموزش سی و ششم با انواع Modifier ها آشنا خواهیم شد). نام انتخابی برای اولین متد showGrandfatherHeight به معنای "قد پدر بزرگ را نشان بده" می باشد. دستوری که برای این متد در نظر گرفته شده اند، به این صورت است که می بایست مقدار شیئ ایجاد شده از روی کلاس String تحت عنوان height به معنی "قد" که دارای مقدار اولیه Short به معنی "کوتاه" می باشد را نمایش دهد. متد دوم showGrandfatherSkinColor به معنای "رنگ پوست پدر بزرگ را نشان بده" می باشد. دستوری که برای این متد در نظر گرفته شده اند، به این صورت است که می بایست مقدار شیئ ایجاد شده از روی کلاس String تحت عنوان skinColor به معنی "رنگ پوست" دارای مقدار اولیه Bright به معنی "روشن" می باشد را نمایش دهد. متد سوم showGrandfatherBoldness به معنای "میزان طاسی پدر بزرگ را نشان بده" می باشد. دستوری که برای این متد در نظر گرفته شده اند، به این صورت است که می بایست مقدار شیئ ایجاد شده از روی کلاس String تحت عنوان boldness به معنی "میزان طاسی" دارای مقدار اولیه Bold به معنی "طاس" می باشد را نمایش دهد. متد چهارم showGrandfatherBehavior به معنای "خلق و خوی پدر بزرگ را نشان بده" می باشد. دستوری که برای این متد در نظر گرفته شده اند، به این صورت است که می بایست مقدار شیئ ایجاد شده از روی کلاس String تحت عنوان behavior به معنی "خلق و خود" دارای مقدار اولیه Angry به معنی "عصبانی" می باشد را نمایش دهد. متد پنجم showGrandfatherCreativity به معنای "خلاقیت پدر بزرگ را نشان بده" می باشد. دستوری که برای این متد در نظر گرفته شده اند، به این صورت است که می بایست مقدار شیئ ایجاد شده از روی کلاس String تحت عنوان creativity به معنی "خلاقیت" دارای مقدار اولیه Very Creative به معنی "خیلی خلاق" می باشد را نمایش دهد. متد ششم showGrandfatherActivity به معنای "فعالیت پدر بزرگ را نشان بده" می باشد. دستوری که برای این متد در نظر گرفته شده اند، به این صورت است که می بایست مقدار شیئ ایجاد شده از روی کلاس String تحت عنوان Activity به معنی "فعالیت" دارای مقدار اولیه Active به معنی "فعال" می باشد را نمایش دهد. در نهایت متد هفتم showGrandfatherNationality به معنای "ملیت پدر بزرگ را نشان بده" می باشد. دستوری که برای این متد در نظر گرفته شده اند، به این صورت است که می بایست مقدار شیئ ایجاد شده از روی کلاس String تحت عنوان nationality به معنی "ملیت" دارای مقدار اولیه Iranian به معنی "ایرانی" می باشد را نمایش دهد. اکنون به منظور تست کردن برنامه خود، یک شیئ از روی کلاس Grandfather در کلاس ActionClass ایجاد کرده سپس متدهای موجود در کلاس پدر بزرگ را فرا می خوانیم. برای این منظور، کلاس ActionClass را باز کرده و آن را به شکل زیر تکمیل می کنیم:

  1. public class ActionClass {
  2. public static void main(String[] args) {
  3. Grandfather grandfatherObject = new Grandfather();
  4. grandfatherObject.showGrandfatherHeight();
  5. grandfatherObject.showGrandfatherSkinColor();
  6. grandfatherObject.showGrandfatherBoldness();
  7. grandfatherObject.showGrandfatherBehavior();
  8. grandfatherObject.showGrandfatherCreativity();
  9. grandfatherObject.showGrandfatherActivity();
  10. grandfatherObject.showGrandfatherNationality();
  11.  
  12. }
  13.  
  14. }

همانطور که در کد فوق ملاحظه می شود، پس از ساخت یک شیئ از روی کلاس Grandfather تحت عنوان grandfatherObject به معنی "شیئ پدر بزرگ"، از این شیئ استفاده کرده و متدهای ایجاد شده در کلاس "پدر بزرگ" را فرا می خوانیم. حال پس از اجرای برنامه خروجی مشاهده خواهد شد:

920526-j33-IMAGE 2.jpg

می بینیم که کلیه Attribute ها و Behavior هایی که برای کلاس پدر بزرگ تعریف شده بودند نمایش داده می شوند. اکنون نوبت به تکمیل کلاس پدر می رسد. برای این منظور کلاس Father را باز کرده و آن را به شکل زیر تکمیل می کنیم:

  1. public class Father extends Grandfather {
  2.  
  3. }

در کد فوق کلید واژه extends به این معنا است که کلاس Father خصوصیات خود را از کلاس Grandfather به ارث خواهد برد. به عبارت دیگر از این پس هر ویژگی که کلاس پدر بزرگ داشته باشد، کلاس پدر دقیقاً همان ویژگی ها را به ارث خواهد برد. همانطور که در قسمت سی و دوم گفته شد، پدر برخی خصوصیاتش با خصوصیات پدر بزرگ متفاوت است. به عبارت دیگر پدر بزرگ دارای خلق و خوی عصبانی هستند در حالیکه پدر خوش رفتار می باشند، پدر بزرگ خیلی خلاق هستند اما پدر خلاقیتش به اندازه پدر بزرگ نیست. از سوی دیگر پدر دارای دو ویژگی دیگر است که پدر بزرگ فاقد آن ها بود که عبارتند از تحصیلات لیسانس و همچنین میزان مطالعه زیاد. در زبان برنامه نویسی جاوا به منظور حل مشکلاتی از این دست از دستور Override استفاده می شود. به عبارت دیگر زمانیکه بخواهیم که یک Subclass برخی از ویژگی های Superclass را به ارث نبرد، می بایست آن خصوصیات را Override یا "رونویسی" کرد. برای این منظور کلاس پدر را به شکل زیر Override می کنیم:

  1. public class Father extends Grandfather {
  2. @Override
  3. public void showGrandfatherBehavior() {
  4. String behavior = "Well=behaved";
  5. System.out.println(behavior);
  6. }
  7. @Override
  8. public void showGrandfatherCreativity() {
  9. String creativity = "Creative";
  10. System.out.println(creativity);
  11. }
  12. }

در حقیقت Override کردن به این شکل صورت می گیرد که ما می بایست پیش از نوشتن نام متد از دستور @Override استفاده کرده سپس آن متد را مجدداً نوشته وصرفاً تغییری در Attribute های آن متد بوجود می آوریم. همانطور که در کد فوق مشاهده می شود، از کل متدهای موجود در کلاس پدر بزرگ فقط دو نمونه که نیاز به Override شدن داشتند را مجدداً نوشته و مقدار آن ها را تغییر داده ایم. در واقع مقدار نمونه behavior را معادل با Well-behaved به معنی "خوش رفتار" در نظر گرفته ایم و مقدار نمونه creativity را معادل با Creative به معنی "خلاق" در نظر گرفته ایم(اگر خاطرمان باشد مقدار این نمونه برای کلاس پدر بزرگ معادل با Very Creative به معنی "بسیار خلاق" بود). اکنون که موارد مد نظر را Override کردیم، نوبت به اضافه کردن خصوصیاتی می رسد که فقط در پدر وجود دارند که عبارتند از مدرک لیسانس و مطالعه زیاد پدر. از این رو کلاس خو را به شکل زیر تکمیل می کنیم:

  1. public class Father extends Grandfather {
  2. @Override
  3. public void showGrandfatherBehavior() {
  4. String behavior = "Well-behaved";
  5. System.out.println(behavior);
  6. }
  7. @Override
  8. public void showGrandfatherCreativity() {
  9. String creativity = "Creative";
  10. System.out.println(creativity);
  11. }
  12. public void showFatherEducation() {
  13. String education = "BA";
  14. System.out.println(education);
  15. }
  16. public void showFatherStudyTime() {
  17. String studyTime = "Much";
  18. System.out.println(studyTime);
  19. }
  20.  
  21. }

همانطور که ملاحظه می شود متدی جدید تحت عنوان showFatherEducation به معنی "تحصیلات پدر را نشان بده" با یک شیئ جدید از کلاس String تحت عنوان education به معنی "تحصیلات" اضافه شده است. مقدار اولیه در نظر گرفته شده برای نمونه education معادل با BA به معنی "لیسانس" است(عبارت BA مخفف واژگان Bachelor of Arts می باشد). سپس متدی دیگری تحت عنوان showFatherStudyTime به معنی "میزان مطالعه پدر را نشان بده" ایجاد کرده و شیئی از کلاس String تحت عنوان studyTime به معنی "زمان مطالعه" در آن ایجاد کرده و مقدار اولیه وارد شده برای نمونه studyTime را معادل با Much به معنی "زیاد" قرار داده ایم. به طور خلاصه این دو متد جدیدی که ایجاد کردیم فقط مخصوص کلاس پدر و کلاس های دیگری است که از این کلاس ارث بری می کنند می باشد(منظور کلاس پسر است). برای مشاهده کردن عملکرد کلاس پدر، در کلاس ActionClass یک شیئ از روی کلاس پدر ساخته و متدهای آن را به صورت زیر فرا می خوانیم:

  1. public class ActionClass {
  2. public static void main(String[] args) {
  3. // Grandfather grandfatherObject = new Grandfather();
  4. // grandfatherObject.showGrandfatherHeight();
  5. // grandfatherObject.showGrandfatherSkinColor();
  6. // grandfatherObject.showGrandfatherBoldness();
  7. // grandfatherObject.showGrandfatherBehavior();
  8. // grandfatherObject.showGrandfatherCreativity();
  9. // grandfatherObject.showGrandfatherActivity();
  10. // grandfatherObject.showGrandfatherNationality();
  11.  
  12. Father fatherObject = new Father();
  13. fatherObject.showGrandfatherHeight();
  14. fatherObject.showGrandfatherSkinColor();
  15. fatherObject.showGrandfatherBoldness();
  16. fatherObject.showGrandfatherBehavior();
  17. fatherObject.showGrandfatherCreativity();
  18. fatherObject.showGrandfatherActivity();
  19. fatherObject.showGrandfatherNationality();
  20. fatherObject.showFatherEducation();
  21. fatherObject.showFatherStudyTime();
  22.  
  23. }
  24.  
  25. }

همانطور که در کد فوق مشاهده می شود کدهای مربوط به کلاس پدر بزرگ را به منظور جلوگیری از شلوغ شدن خروجی برنامه Comment کرده ایم. حال یک شیئ از روی کلاس پدر به اسم fatherObject به معنی "شیئ پدر" ساخته و کلیه متدهای مربوط به پدر بزرگ به علاوه دو متد جدید مربوط به پدر را در آن فرا می خوانیم. اکنون می توانیم برنامه را اجرا کنیم:

920526-j33-IMAGE 3.jpg

همانطور که در خروجی برنامه مشاهده می شود، کلاس پدر کلیه خصوصیات کلاس پدر بزرگ را به ارث برده است با این تفاوت که مقدار نمونه های behavior و creativity به ترتیب به مقادیر Well-behaved و Creative تغییر پیدا کرده اند یا به عبارتی بهتر بگوییم Override شده اند. علاوه بر این پدر دارای دو Attribute دیگر بود که با دایره قرمز رنگ دوم در تصویر فوق مشخص شده اند(علاوه بر این اگر به کد خود به دقت بیشتری نگاه کنیم خواهیم دید که متدهایی که کلاس پدر از کلاس پدر بزرگ به ارث برده است مرتبط با پدر بزرگ هستند مثلا متد showGrandfatherHeight اما متدهای جدید مرتبط به خود کلاس پدر هستند). اکنون زمان آن فرا رسیده است که به تکمیل کلاس پسر که آخرین کلاس است بپردازیم. برای این منظور کلاس پسر را باز نموده و آن را به صورت زیر تکمیل می کنیم:

  1. public class Son extends Father{
  2.  
  3. }

در حقیقت از آنجا که می خواهیم کلاس پسر کلیه خصوصیات خود را از کلاس پدر به ارث ببرد، پس کلید واژه extends را نوشته و سپس نام کلاس Father را می نویسیم. به طور خلاصه بایستی گفت که از آنجا که کلاس پدر برخی خصوصیات خود را از کلاس پدر بزرگ به ارث می برد و کلاس پسر هم برخی خصوصیات خود را قرار است از کلاس پدر به ارث ببرد، این نتیجه را می توان گرفت که کلاس پسر آن دسته از خصوصیاتی را که کلاس پدر از کلاس پدر بزرگ به ارث برده بود را نیز به ارث خواهد برد. اگر به قسمت آموزشی سی و دوم رجوع کنیم، خواهیم دید که پسر بر خلاف پدر و پدر بزرگ خود قد بلند است، اصلاً طاس نیست، همانند پدر بزرگ خود عصبانی است، بر خلاف پدرش که لیسانس دارد، پسر فوق لیسانس دارد و در نهایت خیلی اهل مطالعه است. حال با آگاهی از این موارد خواهیم توانست کد مربوط به کلاس پسر را ویرایش نماییم:

  1. public class Son extends Father {
  2. @Override
  3. public void showGrandfatherHeight() {
  4. String height = "Tall";
  5. System.out.println(height);
  6. }
  7. @Override
  8. public void showGrandfatherBoldness() {
  9. String boldness = "Not Bold";
  10. System.out.println(boldness);
  11. }
  12. @Override
  13. public void showFatherEducation() {
  14. String education = "MA";
  15. System.out.println(education);
  16. }
  17. @Override
  18. public void showFatherStudyTime() {
  19. String studyTime = "Very Much";
  20. System.out.println(studyTime);
  21. }
  22.  
  23. }

همانطور که در کد فوق مشاهده می شود، متد اول مربوط به Override قد است که مقدار آن Tall به معنی "بلند" قرار داده شده است، Override دوم مربوط به طاسی است که مقدار آن Not Bold به معنی "طاس نیست" قرار داده شده، Override سوم مربوط به خلق و خو است که معادل با Angry به معنی "عصبانی" قرار داده شده، Override چهارم مربوط به سطح تحصیلات است که معادل با MA به معنی "فوق لیسانس" قرار داده شده و در نهایت Override پنجم مربوط به میزان مطالعه است که مقدار آن Very Much به معنی "خیلی زیاد" قرار داده شده است(عبارت MA مخفف واژگان Master of Arts است). اکنون می توانیم به کلاس ActionClass رفته و آن را به شکل زیر بازنویسی کنیم:

  1. public class ActionClass {
  2. public static void main(String[] args) {
  3. // Grandfather grandfatherObject = new Grandfather();
  4. // grandfatherObject.showGrandfatherHeight();
  5. // grandfatherObject.showGrandfatherSkinColor();
  6. // grandfatherObject.showGrandfatherBoldness();
  7. // grandfatherObject.showGrandfatherBehavior();
  8. // grandfatherObject.showGrandfatherCreativity();
  9. // grandfatherObject.showGrandfatherActivity();
  10. // grandfatherObject.showGrandfatherNationality();
  11.  
  12. // Father fatherObject = new Father();
  13. // fatherObject.showGrandfatherHeight();
  14. // fatherObject.showGrandfatherSkinColor();
  15. // fatherObject.showGrandfatherBoldness();
  16. // fatherObject.showGrandfatherBehavior();
  17. // fatherObject.showGrandfatherCreativity();
  18. // fatherObject.showGrandfatherActivity();
  19. // fatherObject.showGrandfatherNationality();
  20. // fatherObject.showFatherEducation();
  21. // fatherObject.showFatherStudyTime();
  22.  
  23. Son sonObject = new Son();
  24. sonObject.showGrandfatherHeight();
  25. sonObject.showGrandfatherSkinColor();
  26. sonObject.showGrandfatherBoldness();
  27. sonObject.showGrandfatherBehavior();
  28. sonObject.showGrandfatherCreativity();
  29. sonObject.showGrandfatherActivity();
  30. sonObject.showGrandfatherNationality();
  31. sonObject.showFatherEducation();
  32. sonObject.showFatherStudyTime();
  33.  
  34. }
  35.  
  36. }

همانطور که در کد فوق مشاهده می شود کلیه ی کد های پیشین را Comment کرده ایم و سپس یک شیئ از روی کلاس Son به اسم sonObject به معنی "شیئ پسر" ساخته ایم و پس از آن کلیه ی متدها را فرا خوانده ایم. پس از اجرای برنامه تصویر زیر مشاهده خواهد شد:

920526-j33-IMAGE 4.jpg

همانطور که در تصویر فوق مشاهده می شود، بیضی قرمز رنگ اول نشانگر اولین Override در کلاس Son است که متد مرتبط با قد را بازنوسی کرده است. بیضی قرمز رنگ دوم نشانگر دومین Override است که متد مرتبط با طاسی را بازنویسی کرده است. بیضی قرمز رنگ سوم نشانگر سومین Override است که متد مرتبط با خلق و خو را بازنوسی کرده است و در نهایت بیضی قرمز رنگ چهارم نشانگر چهارمین و پنجمین Override است که متدهای مرتبط با سطح تحصیلات و میزان مطالعه را بازنوسی کرده اند. شاید با مثالی که در قسمت پیشین زده شد و پروژه ای که در این قسمت برنامه نوسی شد، بهتر به این مسئله پی ببریم که طراحان زبان برنامه نوسی جاوا دیدشان به شیئ گرایی در این زبان از دید ایشان به اشیاء در دنیای واقعی نشات گرفته است که همین وجه تشابه مابین شیئ گرایی در زبان برنامه نوسی جاوا و روابط اشیاء در دنیای واقعی می تواند ما را در درک بهتر OOP یاری رساند.

چهارشنبه 2 بهمن 1392  11:47 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۳۴: آشنایی با مفهوم Cast در زبان جاوا


پس از آشنایی با مبحث وراثت در زبان برنامه نویسی جاوا در آموزش سی و دوم و سی و سوم، حال نوبت به توضیح پیرامون Cast کردن در برنامه نویسی می رسد (در زبان انگلیسی واژه Cast دارای معانی متفاوتی است و این در حالی است که در زبان برنامه نویس جاوا این واژه تعریف خاصی دارد. از این رو از ترجمه لغوی این اصلاح خودداری می کنیم). و به ادامه مطلب می رویم.

گاهی اوقات در برنامه نویسی برای ما پیش می آید که نیاز داریم تا جنس داده های خود را تغییر دهیم که اصطلاحاً به فرایند تغییر جنس داده ای به داده ای دیگر در زبان برنامه نویسی جاوا Cast کردن گفته می شود. به طور مثال فرض کنیم که ما نیاز داریم تا یک متغیر از جنس int که برای اعداد صحیح مورد استفاده قرار می گیرد را به متغیر double که برای اعداد اعشاری مورد استفاده قرار می گیرد مبدل سازیم که برای این کار می بایست از عمل Cast کردن استفاده کنیم. لازم به ذکر است پس از آنکه ما مثلاً یک متغیر را به یک متغیر دیگر Cast کردیم در واقع ما متغیر قبلی خود را تبدیل به متغیر جدید نکرده ایم بلکه یک متغیر جدید از روی متغیر قبلی خود ساخته ایم که دارای همان جنسی است که مد نظر ما است. از میان کلیه متغیرها تنها متغیری که قابلیت Cast شدن ندارد متغیرهایی از جنس boolean هستند که در آموزش های پیشین با آن آشنا شده ایم(به علاقمندان به طراحی اپلیکیشن های اندروید توصیه می شود این مبحث را با دقت فرا گیرند چرا که از Cast به کرات در کدهای خود که برای سیستم عامل اندروید طراحی می کنند استفاده خواهند کرد).

در حقیقت داده اولیه که ما می خواهیم آن ها را به داده ای از جنس دیگری تبدیل کنیم در اصطلاح برنامه نویسی داده Source به معنی "منبع" نامیده می شود و داده جدید ایجاد شده داده Destination به معنی "مقصد" نامیده می شود. نکته ای که در اینجا حائز اهمیت است این است که اگر داده های Destination یا همان "مقصد" از داده Source بزرگ تر باشند فرایند تبدیل به خوبی انجام خواهد شد. برای روشن شدن این مطلب یک مثال می زنیم. فرض کنیم که داده Source ما داده ای از جنس یک متغیر از نوع byte می باشد که قصد داریم تا آن را به داده ای از جنس متغیر دیگری از نوع int تبدیل کنیم(برای آشنایی بیشتر می توان به مبحث Primitive Type ها در آموزش پنجم مراجعه کرد). همانطور که می دانیم متغیر int نسبت به متغیری از جنس byte که هر دو برای ذخیره سازی اعداد صحیح به کار می روند به مراتب مقادیر بزرگ تری را در خود جای می دهد.

گاهی اوقات نیز عکس این قضیه اتفاق می افتد. به عبارت دیگر فضایی که داده Destination از حافظه اشغال می کند نسبت به فضای اشغال شده توسط داده Source کوچکتر است. به طور مثال فرض کنیم که می خواهیم متغیری از جنس int را به متغیری از جنس short که برای ذخیره سازی اعداد صحیح استفاده می شود Cast کنیم. از آن جاییکه فضای ذخیره سازی متغیری از جنس short از متغیری از جنس int به مراتب کمتر است، جاوا این تبدیل را برای ما انجام خواهد داد اما این در حالی است که بایستی شاهد نتایج کمی غیر قابل انتظار باشیم.

حال برای روش شدن مطالب تئوری فوق، پروژه ای جدید تحت عنوان 34th Session به معنی "جلسه سی و چهارم" ایجاد کرده سپس کلاسی به نام Casting در آن ایجاد می کنیم. حال کد اولیه ما به شکل زیر خواهد بود:

  1. public class Casting {
  2. public static void main(String[] args) {
  3.  
  4. }
  5. }

حال یک متغیر از جنس double تحت عنوان doubleVariable به مقدار اولیه 10.2 ایجاد می کنیم. کد تکمیل شده ما به شکل زیر خواهد بود:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. double doubleVariable = 10.2;
  4.  
  5. }
  6. }

متغیر double ایجاد شده به منزله داده Source ما خواهد بود. حال قصد داریم تا این داده را به داده ای از جنس متغیر int که برای ذخیره سازی اعداد صحیح مورد استفاده قرار می گیرد Cast کنیم. برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. double doubleVariable = 10.2;
  4. int integerVariable = (int) doubleVariable;
  5.  
  6. }
  7. }

همانطور که در کد فوق مشاهده می شود ما یک متغیر از جنس int تحت عنوان integerVariable ایجاد کرده و مقدار آن را معادل با مقدار داده Source که در مرحله قبل ایجاد کردیم قرار می دهیم. در واقع در این مرحله ما قصد داریم داده Source که همان متغیر double است را به داده Destination که همان متغیر int است Cast کنیم برای همین منظور پس از علامت مساوی مقابل نام داده Destination یک علامت ( ) قرار داده و نوع داده ای را که می خواهیم داده اولیه به آن Cast شود را می نویسیم و از آن جا که در این مثال می خواهیم داده ما به داده ای از جنس متغیر int تبدیل شود داخل پرانتز نوع متغیر مد نظر که int می باشد را می نویسیم. در اینجا کار ما به اتمام رسیده است. حال برای آن که خروجی برنامه خود را ببینیم نیاز به دستور System.out.println(); داریم. در واقع در مرحله اول نام متغیر اولیه خود یا همان متغیر Source را به صورت زیر می نویسیم:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. double doubleVariable = 10.2;
  4. int integerVariable = (int) doubleVariable;
  5. System.out.println(doubleVariable);
  6.  
  7. }
  8. }

حال اگر برنامه را اجرا کنیم خروجی زیر قابل مشاهده خواهد بود:

920528-34j-IMAGE 1.jpg

در واقع از آنجا که داده اولیه ما از جنس متغیری از نوع double است، ما در خروجی برنامه یک عدد اعشاری خواهیم داشت. حال اگر داده Destination یا همان داده نهایی که پس از Cast شدن داده اولیه در قالب یک متغیر از جنس int قرار گرفته است را در دستور System.out.println(); به صورت زیر قرار دهیم متوجه عملکرد Cast خواهیم شد:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. double doubleVariable = 10.2;
  4. int integerVariable = (int) doubleVariable;
  5. System.out.println(integerVariable);
  6.  
  7. }
  8. }

در واقع در کد فوق نام متغیر Destination که Cast شده می باشد را داخل پرانتز می نویسیم. خروجی برنامه به شکل زیر خواهد بود:

920528-34j-IMAGE 2.jpg

در تصویر فوق می بینیم که جاوا به صورت خودکار پس از Cast کردن داده ای از جنس عدد اعشاری به داده ای از جنس عدد صحیح، عدد را رند کرده است. حال ببینیم عکس این قضیه چه طور ممکن است اتفاق افتد. در این مثال قصد داریم تا Source یی بزرگ تر را به Destination یی کوچک تر از خود Cast کنیم. برای این منظور کد خود را به شکل زیر بازنویسی می کنیم:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. int integerVariable = 1000000;
  4.  
  5. }
  6. }

در واقع در مثال فوق داده اولیه ما از جنس متغیری از نوع int است که مقدار اولیه آن معادل با 1000000 است. متغیری از جنس int همواره نسبت به متغیری از جنس short دارای ظرفیت بیشتری برای ذخیره سازی اعداد صحیح می باشد. حال می خواهیم متغیر int مثال فوق را به متغیر short که نام آن shortVariable است Cast کنیم. برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. int integerVariable = 1000000;
  4. short shortVariable = (short) integerVariable;
  5.  
  6. }
  7. }

حال در مرحله اول برای به نمایش در آوردن خروجی برنامه در دستور System.out.println(); نام متغیر خود از جنس int را می نویسیم و سپس برنامه را اجرا می کنیم:

920528-34j-IMAGE 3.jpg

می بینیم که همان Value یی که برای متغیر int خود در نظر گرفته بودیم در پنجره Console به نمایش در آمده است. حال نام متغیر short که Cast شده است را به صورت زیر فرا می خواهیم:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. int integerVariable = 1000000;
  4. short shortVariable = (short) integerVariable;
  5. System.out.println(shortVariable);
  6.  
  7. }
  8. }

پس از اجرای برنامه خروجی زیر مشاهده خواهد شد:

920528-34j-IMAGE 4.jpg

همانطور که ملاحظه می شود از آنجا که ظرفیت متغیری از جنس short نسبت به متغیری از جنس int به مراتب کمتر است، خروجی برنامه نیز عددی به مراتب کوچکتر از مقدار اولیه متغیر int پیش از Cast شدن خواهد بود.

چهارشنبه 2 بهمن 1392  11:49 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۳۵: نحوه Cast کردن یک شیئ به یک متغیر


در آموزش گذشته با نحوه Cast کردن متغیر ها به یکدیگر آشنا شدیم. همانطور که در جلسه سی و چهارم گفته شد Cast کردن به منزله یکی از دستورات کاربردی در برنامه نویسی اپلیکیشن های سیستم عامل اندروید می باشد. از این رو به علاقمندان پیشنهاد می شود که برای درک بهتر Cast در زبان برنامه نویسی جاوا، مطالب آموزشی قسمت های سی و چهارم و سی و پنجم را به خوبی مطالعه کنند.

حال در این جلسه قصد داریم تا ببینیم که به چه نحوی می توان یک شیئ را به یک متغیر و بالعکس Cast نمود. پس از شروع نیاز است تا پروژه ای جدید تحت عنوان 35th Session به معنی "جلسه سی و پنجم" ایجاد کرده سپس کلاسی با نام Casting در آن بسازیم.

چیزی که در زبان برنامه نویسی جاوا امکان پذیر نیست، Cast کردن یک Object به یک Variable و یا Cast کردن یک Variable به یک Object است. در عوض در API زبان برنامه نویسی جاوا برای هر یک از انواع متغیر ها یک کلاس با همان نام در نظر گرفته شده که عملیات Cast کردن را برای ما انجام دهد. در واقع در زبان برنامه نویسی جاوا ما هشت نوع متغیر از نوع Primitive Type داریم که عبارتند از boolean, double, float, int, short, long, byte, char و اگر توجه کنیم می بینیم که کلیه این متغیر ها با حروف کوچک شروع می شوند. حال کلاس هایی که در API زبان جاوا برای هر یک از این متغیر های در نظر گرفته شده هم نام با نام متغیر بوده با این تفاوت که با حرف بزرگ نوشته می شوند که عبارتند از Boolean, Double, Float, Integer, Short, Long, Byte, Character (البته دو مورد Integer و Character به صورت کامل نوشته می شوند و این در حالی است که نوع متغیر آن ها به ترتیب عبارت است از int و char ).

اکنون قصد داریم تا یک Object از جنس کلاس Integer ایجاد کرده و یک Value هم به آن اختصاص دهیم(به حرف اول کلید واژه Integer توجه کنید که به صورت بزرگ نوشته شده است). برای این منظور به صورت زیر عمل می کنیم:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. Integer integerObject = new Integer(123);
  4. }
  5. }

همانطور که ملاحظه می شود طرز ساخت یک شیئ از روی کلاس Integer به این شکل است که اول نام کلاس مد نظر را نوشته سپس نامی مرتبط را آن را در نظر می گیریم که در این مثال نام integerObject در نظر گرفته شده است. سپس یک علامت مساوی قرار داده و از آنجا که می خواهیم یک شیئ جدید از روی این کلاس بسازیم نیاز است تا کلید واژه new را بنویسیم و سپس نام کلاس را مجدد بنویسم. در داخل پرانتزی که مقابل کلید واژه Integer قرار دارد می بایست یک پارامتر تعریف کنیم. به عبارت دیگر این پارامتر همان Value کلاس Integer خواهد بود. حال همانند مابقی Object ها می توانیم از این شیئ ساخته شده در هر کجای برنامه که بخواهیم استفاده کنیم. زمانیکه بخواهیم از این شیئ به عنوان یک متغیر استفاده کنیم، در کلاس Integer متدی تعریف شده است که این کار را برای ما خواهد کرد. اگر بخواهیم یک Value از جنس متغیر int از شیئی که در بالا ساختیم به دست آوریم، می بایست به شکل زیر عمل کنیم:

  1. public class Casting {
  2. public static void main(String[] args) {
  3. Integer integerObject = new Integer(123);
  4. int newValue = integerObject.intValue();
  5. }
  6. }

در واقع در خطی از کد که اضافه کردیم این دستور را به سیستم می دهیم که یک متغیر از جنس int تحت عنوان newValue به معنی "مقدار جدید" بسازد سپس مقدار این متغیر را مساوی با نام شیئی که در بالا ساختیم قرار داده به ضمیمه متد intValue() که وظیفه اش تبدیل مقدار شیئ بالا به یک متغیر است(لازم به ذکر است که اگر شیئ ساخته شده در مرحله قبل از جنس کلاس Double بود می توانستیم از متد doubleValue()استفاده کنیم). یکی از موارد رایج استفاده از تبدیل یک شیئ به یک متغیر زمانی است که می خواهیم مقدار یک کلاس از جنس String را به یک متغیر از جنس مثلاً int تبدیل کنیم. برای روشن شدن مطلب فوق نیاز است تا یک سناریو تعریف کنیم سپس با توجه به سناریوی موجود یک برنامه بنویسیم. فرض کنیم که می خواهیم برنامه ای طراحی کنیم که در آن کاربر اول نام خود را وارد کند سپس تاریخ تولد خود را بر اساس تاریخ شمسی وارد کند. سپس برنامه سن ایشان را محاسبه کرده و در نهایت جمله ای در پنجره Console به نمایش در می آورد مبنی بر اینکه مثلاً آقا یا خانم ایکس شما 30 سال سن دارید. برای شروع این پروژه کار خود را به صورت زیر آغاز می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class Casting {
  4. public static void main(String[] args) {
  5. Scanner keyboardInput = new Scanner(System.in);
  6. System.out.println("Please enter your name");
  7.  
  8. }
  9. }

در این کد از کلاس Scanner برای دسترسی به ورودی از طریق کیبورد استفاده خواهیم کرد(در آموزش های پیشین به کرات از این کلاس استفاده شده است. برای آشنایی بیشتر با این کلاس به آموزش های یازدهم، دوازدهم و سیزدهم رجوع نمایید). نام کلاس Scanner خود را keyboardInput به معنی "ورودی کیبورد" می گذاریم(لازم به ذکر است برای دسترسی به کلاس Scanner می بایست این کلاس را در برنامه خود Import یا وارد کنیم بنابراین اولین خط از کد فوق برای همین مسئله نوشته شده است).سپس در دستور System.out.println(); عبارت Please enter your name به معنی "لطفاً نام خود را وارد کنید" را نوشته ایم. حال قصد داریم تا این امکان را برای کاربر فراهم کنیم که بتواند نام خود را از طریق کیبورد وارد برنامه کند. برای همین منظور کد فوق را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class Casting {
  4. public static void main(String[] args) {
  5. Scanner keyboardInput = new Scanner(System.in);
  6. System.out.println("Please enter your name");
  7. System.out.print("My name is ");
  8. String name = keyboardInput.next();
  9.  
  10. }
  11. }

سپس در دستور System.out.print(); عبارت My name is به معنی "نام من هست" را وارد می کنیم. اگر توجه کرده باشید در این دستور از واژه println استفاده نکرده و در عوض از عبارت print استفاده کرده ایم چرا که نمی خواهیم برنامه پس از اجرای این دستور به خط بعد برود. سپس یک نمونه از کلاسی از جنس String تحت عنوان name به معنی "نام" ایجاد کرده و مقدار آن را ورودی کیبورد به کلاس Scanner قرار می دهیم. برای همین منظور پس از علامت مساوی نام کلاس Scanner را نوشته سپس از متد next() استفاده می کنیم که وظیفه اش گرفتن ورودی کیبورد است. حال قصد داریم تا کد خود را تکمیل کنیم تا بتوانیم تاریخ تولد را هم از طریق کیبورد بگیریم:

  1. import java.util.Scanner;
  2.  
  3. public class Casting {
  4. public static void main(String[] args) {
  5. Scanner keyboardInput = new Scanner(System.in);
  6. System.out.println("Please enter your name");
  7. System.out.print("My name is ");
  8. String name = keyboardInput.next();
  9. System.out.print("I was born in ");
  10. String date = keyboardInput.next();
  11. }
  12. }

مجدد از دستور System.out.print(); استفاده می کنیم تا عبارت I was born in به معنی "من در ... به دنیا آمدم" را به نمایش در آوریم. سپس یک نمونه دیگر از کلاس String به اسم date به معنی "تاریخ" ایجاد می کنیم و مقدار آن را همانند name قرار می دهیم. حال اگر برنامه را اجرا کنیم با تصویر زیر مواجه خواهیم شد:

920526-j35-IMAGE 1.jpg

تا اینجای کار برنامه ما به درستی کار می کند. حال می خواهیم مقدار کلاس String تحت عنوان date را گرفته و از سال 1392 کم کنیم تا ببینیم فردی به اسم بهزاد چند ساله است. نکته ای که در اینجا می بایست مد نظر قرار داد این است که مقدار date اگر چه که 1362 است اما این در حالی است که جنس آن همانند مقدار name چیزی از جنس کلمه است و ما به هیچ وجه نمی توانیم آن را از عدد 1392 کم کنیم. برای این منظور نیاز است تا از Cast کردن date که یک String است به یک متغیر از جنس int که در این قسمت از آموزش فرا خواهیم گرفت استفاده کنیم. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class Casting {
  4. public static void main(String[] args) {
  5. Scanner keyboardInput = new Scanner(System.in);
  6. System.out.println("Please enter your name");
  7. System.out.print("My name is ");
  8. String name = keyboardInput.next();
  9. System.out.print("I was born in ");
  10. String date = keyboardInput.next();
  11. int dateValueToInt = Integer.parseInt(date);
  12. }
  13. }

در این کد تکمیل شده ما یک متغیر از جنس int تحت عنوان dateValueToInt به معنی "تبدیل مقدار date به متغیری از جنس int" ایجاد کرده و مقدار آن را Integer.parseInt(date) قرار داده ایم. در واقع کاری که ما در این خط از کد انجام خواهیم داد این است که مقدار متغیر خود را مساوی با کلاسی تحت عنوان Integer قرار داده سپس متدی تحت عنوان parseInt() را فرا می خوانیم تا به ما کمک کند تا با قرار دادن پارامتری داخل پرانتز آن، آن را به یک داده از جنس int تبدیل کند. برای همین منظور نام شیئی که برای گرفتن تاریخ تولد مورد استفاده قرار گرفت را که همان date است را داخل پرانتز وارد می کنیم. تا اینجای کار توانسته ایم با موفقیت تاریخ تولد کاربر را گرفته و آن را از یک string یا "کلمه" به یک int یا "عدد" صحیح تبدیل کنیم. حال نیاز داریم تا آن را از عدد 1392 کم کرده و نتیجه را روی صفحه مانیتور نمایش دهیم. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class Casting {
  4. public static void main(String[] args) {
  5. Scanner keyboardInput = new Scanner(System.in);
  6. System.out.println("Please enter your name");
  7. System.out.print("My name is ");
  8. String name = keyboardInput.next();
  9. System.out.print("I was born in ");
  10. String date = keyboardInput.next();
  11. int dateValueToInt = Integer.parseInt(date);
  12. int yourAge = 1392 - dateValueToInt;
  13. System.out.println("Dear " + name + " you are " + yourAge
  14. + " years old.");
  15.  
  16. }
  17. }

در کد فوق پس از تکمیل یک متغیر از جنس int به اسم yourAge به معنی "سن شما" ایجاد کرده ایم و مقدار آن را برابر با حاصل تفریق عدد 1392 از مقدار متغیر dateValueToInt قرار داده ایم. سپس در دستور System.out.println(); که پس از آن قرار گرفته است کلمه Dear به معنی "عزیز" را به علاوه name می کنیم که در برگیرنده نام کاربر خواهد بود. سپس عبارت you are به معنی "شما هستید" را به علاوه نام متغیری می کنیم که قرار است تاریخ تولد کاربر را از عدد 1392 کسر کند که همان yourAge است. در نهایت عبارت years old را به انتهای عبارت خود اضافه می کنیم. پس از اجرای برنامه خروجی زیر مشاهده خواهد شد:

920526-j35-IMAGE 2.jpg

در جلسه سی و ششم پیرامون Access Control یا به عبارتی "کنترل کردن سطح دسترسی" به کلاس ها، متغیرها و متد ها در زبان برنامه نویسی جاوا صحبت خواهیم کرد.

چهارشنبه 2 بهمن 1392  11:50 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۳۶: آشنایی با سطوح دسترسی در زبان جاوا


فرض کنیم که قرار است به عنوان سرپرست گروهی از برنامه نویسانی باشیم که روی طراحی یک نرم افزار کار می کنند. وظیفه ای که مدیر پروژه بر عهده ما گذاشته است این می باشد که کنترل کنیم که هر برنامه نویسی بنا به وظیفه ای که دارد تا چه حدی به دیگر کلاس ها، متغیر ها و متد هایی که توسط دیگر برنامه نویسان تولید می شود می تواند دسترسی داشته باشد. حال اگر ما به عنوان سرپرست مابقی برنامه نویسان کار خود را به خوبی انجام دهیم، به نظر می رسد که مشکلی حادی در این رابطه بوجود نیاید. حال فرض کنیم که ما آن طور که باید و شاید در مورد Access Control در زبان برنامه نویسی جاوا آگاهی نداریم.

در این جا است که پروژه ما با مشکلات جدی مواجه خواهد شد چرا به طور مثال برنامه نویسی که نمی بایست به یک متغیر از جنس int دسترسی داشته باشد حال این امکان برایش فراهم شده و ایشان هم بدون هیچ سوء قصدی مقدار اولیه آن متغیر را تغییر داده اند و نتیجه ای که برنامه در حین کار می بایست داشته باشد به نتیجه ای غیر قابل باور تبدیل شده است.

برای درک بهتر سطح دسترسی در زبان برنامه نویسی جاوا پروژه ای تحت عنوان 36th Session به معنی "جلسه سی و ششم" ایجاد می کنیم.

در حقیقت با قرار دادن کلید واژه public پیش از یک کلاس، متد و یا متغیر این دستور را به برنامه خود می دهیم که این کلاس، متد و یا متغیر در دیگر بخش های برنامه و توسط دیگر کلاس ها قابل دسترسی است. به عبارت دیگر از هر جای دیگر برنامه من جمله بخش های دیگر همان کلاس، دیگر پکیج ها، کلاس های ارث بری شده از آن می توان به عناصر public دسترسی داشته و در صورت لزوم تغییری در آن ها ایجاد کرد.

کلید واژه protected حاکی از آن است که عنصری که این کلید واژه قبل از آن قرار گرفته است در همان کلاس، دیگر پکیج ها و کلاس های ارث بری شده از آن قابل دسترسی خواهد بود.

کلید واژه private این معنا را می رساند که مثلا متغیری که private است فقط و فقط در همان کلاس قابل دسترسی خواهد بود.

حال زمانیکه هیچ کلید واژه محدود کننده ای قبل از نام یک کلاس، متد و یا متغیر نباشد، این سطح دسترسی Package Access نامیده می شود و بدان معنا است که عنصری که فاقد هرگونه public, protected, private باشد در همان کلاس و یا دیگر کلاس های موجود در همان پکیج قابل دسترسی خواهد بود.

برای روشن شدن تفاوت مابین این چهار سطح دسترسی می توان از جدول زیر کمک گرفت:

920506-j36-IMAGE 1.jpg

حال برای درک بهتر کلیه سطوح دسترسی نیاز داریم تا یک پروژه کوچک تعریف کرده و بر اساس آن یک برنامه بنویسیم. فرض کنیم که می خواهیم دو کلاس داخل یک پکیج ایجاد کنیم که یکی از آن ها دارای محدودیت بیشتری نسبت به کلاس دیگری است.

در پروژه ای که در ابتدای این آموزش ایجاد کردیم یک کلاس تحت عنوان MainClass به معنی کلاس اصلی ایجاد می کنیم. پیش از زدن دکمه Finish می بایست یک نام برای پکیج خود نیز انتخاب کنیم. برای همین منظور نام MainPackage را نیز به معنی "پکیج اصلی" در نظر می گیریم. برای روش تر شدن مطلب به تصویر زیر توجه کنید:


920506-j36-IMAGE 2.jpg

همانطور که در این تصویر مشاهده می شود جایی که با فلش قرمز مشخص شده می بایست برای نام پکیج نوشته شود و جایی که با فلش سبز رنگ مشخص شده می بایست برای نام کلاس پر شود.

از آنجا که این کلاس قرار است کلاسی باشد که برنامه در آن شروع شود از این رو در حین ساختن آن می بایست گزینه public static void main(String[] args) را تیک بزنیم.

در این مرحله کد ما می بایست به شکل زیر باشد:


  1. package MainPackage;
  2.  
  3. public class MainClass {
  4. public static void main (String[] args){
  5.  
  6. }
  7.  
  8. }

همانطور که در کد بالا ملاحظه می شود در خط اول نام پکیجی که وارد کردیم وارد برنامه شده است. حال اقدام به ایجاد یک کلاس دیگر تحت عنوان SecondClass به معنی "کلاس دوم" می کنیم. از آنجا که این کلاس قرار نیست که به منزله نقطه شروع برنامه باشد گزینه public static void main(String[] args) را تیک نمی زنیم. کد مربوط به کلاس دوم ما می بایست به شکل زیر باشد:

  1. package MainPackage;
  2.  
  3. public class SecondClass {
  4.  
  5. }

حال می خواهیم تا کلاس اول ما یکسری از خصوصیات کلاس SecondClass را به ارث ببرد از این رو کد MainClass را به شکل زیر بازنویسی می کنیم:

  1. package MainPackage;
  2.  
  3. public class MainClass extends SecondClass{
  4. public static void main (String[] args){
  5.  
  6. }
  7.  
  8. }

حال کلاس دوم خود را به شکل زیر تکمیل می کنیم:

  1. package MainPackage;
  2.  
  3. public class SecondClass {
  4. int number = 123;
  5. public void testMethod() {
  6. System.out.println(number);
  7. }
  8. }

در این کد ما یک متغیر از جنس int تحت عنوان number به معنی "شماره" ایجاد کرده سپس یک متد به اسم testMethod ایجاد کرده و در آن دستور داده ایم که مقدار متغیر ما تحت عنوان number در پنجره Console نمایش داده شود. البته این کلاس از آن جا که نقطه آغازین یا همان متد main را ندارد چیزی اجرا نخواهد کرد. حال در کلاس MainClass یک شیئ از روی این کلاس ایجاد می کنیم و آن را در متد main اجرا می کنیم. کد ما در کلاس MainClass به شکل زیر خواهد بود:

  1. package MainPackage;
  2.  
  3. public class MainClass extends SecondClass {
  4. public static void main(String[] args) {
  5. SecondClass myObject = new SecondClass();
  6. myObject.testMethod();
  7. }
  8. }

همانطور که در آموزش های پیشین توضیح داده شد، از روی کلاس SecondClass یک شیئ تحت عنوان myObject به معنی "شیئ من" ساخته سپس در خط بعدی، متد قرار گرفته در آن کلاس را فرا می خوانیم. حال اگر برنامه را اجرا کنیم، تصویر زیر مشاهده خواهد شد:

920506-j36-IMAGE 3.jpg

در واقع عدد 123 مقدار متغیری تحت عنوان number است که در کلاس SecondClass ایجاد شده است. حال می خواهیم تا از قصد سطح دسترسی متد ایجاد شده در SecondClass را محدود کنیم. به عبارت دیگر سطح دسترسی آن را از نوع public به نوع private تغییر می دهیم. کد ما به شکل زیر بازنویسی خواهد شد:

  1. package MainPackage;
  2.  
  3. public class SecondClass {
  4. int number = 123;
  5. private void testMethod() {
  6. System.out.println(number);
  7. }
  8. }

حال به محض اینکه فایل خود را Save کنیم در پنجره Problems خطای زیر ایجاد خواهد شد:

920506-j36-IMAGE 4.jpg

این Error حاکی از آن است که متدی تحت عنوان testMethod از کلاس SecondClass قابل روئیت نمی باشد(چنانچه پنجره Problems باز نباشد می توان از منوی اصلی محیط برنامه نویسی اکلیپس گزینه Window را انتخاب کرده سپس گزینه Show View و در نهایت گزینه Problems را کلیک نماییم). حال اگر به MainClass نگاهی بیندازیم می بینیم که آنجا هم این مشکل خود را نشان خواهد داد:

920506-j36-IMAGE 5.jpg

در واقع به محض Save کردن فایل خود دور نام متد testMethod یک نقطه چین قرار خواهد گرفت و با قرار دادن نشانگر موس خود روی آن می بینیم که اکلیپس به ما پیشنهاد می دهد که سطح دسترسی مرتبط با این متد را تغییر دهیم تا مشکل برنامه رفع گردد. در این پروژه دیدیم که به چه سهولتی می توانیم سطح دسترسی به متدها را در برنامه خود تغییر دهیم.

چهارشنبه 2 بهمن 1392  11:52 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۳۷: آشنایی با متدها در زبان برنامه نویسی


در این قسمت قصد داریم تا متدها را به طور دقیق تر مورد بررسی قرار دهیم. همانطور که قبلاً هم گفته شده هر شیئ در زبان برنامه نویسی جاوا دارای یکسری Attribute و یکسری Behavior می باشد. به طور مثال اگر شیئ ما داری یک متغیر از جنس int است که مقداری را در خود ذخیره می سازد، این متغیر به منزله یک Attribute برای شیئ ما محسوب می شود. از سوی دیگر Behavior ها بخشی از یک کلاس را تشکیل می دهند که قرار است کاری را انجام دهد که هر یک از این بخش ها یک Method نامیده می شود. تا این بخش از آموزش ما بارها و بارها متدهایی را به صورت ناخودآگاه مورد استفاده قرار داده ایم که یکی از این متدها print() می باشد که این وظیفه را دارا است که هر آنچه را که مابین دو پرانتز قرار گرفت را روی صفحه مانیتور به نمایش در آورد. متدها در زبان برنامه نویسی جاوا، هم به همراه Object ها و هم به همراه Class ها مورد استفاده قرار می گیرند.

نحوه ساخت یک متد تا حدودی شبیه به ساخت یک کلاس است. هر دو می توانند Modifier هایی مثل public, private و غیره بگیرند(برای آشنایی بیشتر با Modifier ها به آموزش سی و ششم مراجعه نمایید)، هر دو می بایست با یک علامت } شروع شده و با یک علامت { تکمیل گردند. متد وظیفه ای که بر عهده دارد این است که می بایست پس از آنکه فرا خوانده شد داده یا مقداری را بازگرداند. حال این مقدار می تواند مقدار یک متغیر ساده مثل int و یا double باشد و یا می تواند کلاسی از Object ها باشد.

حال برای درک بهتر متدها، یک پروژه جدید تحت عنوان 37th Session به معنی جلسه "سی و هفتم" ساخته و یک کلاس به نام MainClass به معنی "کلاس اصلی" در آن ایجاد می کنیم. حال کد ما در ابتدای کار می بایست به این شکل باشد:

  1. public class MainClass {
  2.  
  3. }

حال دو متغیر یکی از جنس int تحت عنوان price به معنی "قیمت" به مقدار اولیه 3000000 ایجاد کرده و یک شیئ از روی کلاس String تحت عنوان laptopName به معنی "نام لپ تاپ" به مقدار اولیه The Laptop Name Is Lenovo. به معنی "نام لپ تاپ لنوو هست." ایجاد می کنیم. حال کد تکمیل شده ما می بایست به شکل زیر باشد:

  1. public class MainClass {
  2. int price = 3000000;
  3. String laptopName = "Laptop Name Is Lenovo";
  4.  
  5. }

حال متدی ایجاد می کنیم که وظیفه خواهد داشت این داده ها را در پنجره Console نمایش دهد. کد تکمیل شده به شکل زیر خواهد بود:

  1. public class MainClass {
  2. int price = 3000000;
  3. String laptopName = "Laptop Name Is Lenovo";
  4. public void showData() {
  5. System.out.println(laptopName + " and its price is " + price);
  6. }
  7. }

در واقع هر متد از دو بخش تشکیل شده است، بخش Signature و بخش Body که در مثال فوق Signature با کلید واژه public شروع شده است به این معنی که این متد از هر کجای برنامه ما قابل دسترسی خواهد بود. سپس کلید واژه void مشاهده می شود که به این معنا است که هر موقع متد showData در برنامه فرا خوانده شد، این متد قرار نیست هیچ چیزی به طور مثال داده ای را اصطلاحاً return کند یا بازگرداند وصرفا وظیفه دارد هر آنچه را مابین دو علامت {} قرار گرفته است را مثلاً روی مانیتور نمایش دهد. سپس به نام متد می رسیم که در مثال فوق نام showData به معنی "داده ها را نشان بده" می باشد(همانطور که در قسمت های پیشین توضیح داده شد، نحوه نام گذاری متدها به این شکل است که کلمه اول در نام متد می بایست یک فعل باشد و علت این مسئله هم این است که از آنجا که متدها وظیفه دارند کاری انجام دهند، پس بهتر است در نامگذاری این دقت شود که نام متد هم با کاری که قرار است انجام دهد یکی باشد). سپس دو پرانتز به شکل () مقابل نام متد قرار می دهیم که وظیفه این پرانتز ها این است که اگر خواستیم پارامترهایی را برای متد خود در نظر بگریم داخل این دو پرانتز بنویسیم. در واقع ما با این کار می توانیم زمانیکه متد را فرا می خوانیم داده هایی را هر جنس در لحظه به متد خود منتقل نماییم. در این مثال ما قصد نداریم تا هیچ داده ای را به این شکل در حین فرا خواندن متد خود منتقل نماییم. در آموزش سی و هشتم نمونه ای از متدی را توضیح خواهیم داد که داخل پرانتز مقابل نام متد داده ای را قرار داده تا در حین فرا خواندن آن متد، آن داده هم منتقل شود. حال نوبت به بررسی Body متد خود می رسد. در حقیقت همانطور که در کد فوق ملاحظه می شود Body متد ما تحت عنوان showData حاوی یک دستور System.out.println(); برای نمایش داده چیزی روی صفحه مانیتور است. نکته ای که در اینجا حائز اهمیت است این است که در این دستور ما به متغیرهایی که قبلاً ایجاد کرده بودیم لینک داده ایم( به عبارت دیگر Body یک متد داخل دو کروشه قرار می گیرد). تا این مرحله از کدنویسی، ما موفق شده ایم تا یک متد که قرار است جمله ای را روی صفحه مانیتور به نمایش درآورد را ایجاد کنیم. حال می بایست این متد را فرا بخوانیم، برای این منظور یک کلاس جدید تحت عنوان ActionClass به معنی "کلاس عملیاتی" ایجاد کرده و از آنجا که این کلاس جدید قرار است به منزله نقطه شروع برنامه باشد پس نیاز داریم تا در حین ساخت آن گزینه public static void main را تیک بزنیم. حال کد ما می بایست به صورت زیر باشد:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4.  
  5. }
  6. }

حال در متد main در کلاس جدیدی که ایجاد کردیم یک شیئ از روی کلاس قبلی به صورت زیر می سازیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myObject = new MainClass();
  5.  
  6. }
  7. }

در کد فوق ما نام کلاسی که می خواهیم از روی آن یک شیئ ایجاد کنیم را نوشته سپس نامی برای آن انتخاب کرده که در این مثال نام myObject به معنی "شیئ من" در نظر گرفته شده است. سپس یک علامت مساوی قرار داده و مجدداً نام کلاسی که می خواهیم شیئ از روی آن ساخته شود را می نویسیم و در نهایت یک علامت (); قرار می دهیم. شیئ ما ساخته شد. حال می خواهیم متدی که در کلاسی که از روی آن یک شیئ ساختیم را فرا بخوانیم. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myObject = new MainClass();
  5. myObject.showData();
  6.  
  7. }
  8. }

برای این منظور نام شیئی که جدیداً ساخته را نوشته سپس یک نقطه قرار داده و سپس نام متدی که در کلاس اصلی خود ساخته بودیم را می نویسیم و در نهایت علامت (); را در انتهای نام متد قرار می دهیم. حال برنامه را اجرا می کنیم:

920506-j37-IMAGE 1.jpg

خواهیم دید که برنامه ما پس از اجرا، متدی را فرا خواند که وظیفه داشت عبارت فوق را روی صفحه مانیتور به نمایش در آورد.

چهارشنبه 2 بهمن 1392  11:53 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۳۸: اضافه کردن پارامتر به متد ها


پس از آشنایی با نحوه ساخت یک متد از پایه، در این قسمت از آموزش قصد داریم تا به بررسی این مسئله بپردازیم که به چه نحوی می توان داده هایی از هر جنس که بخواهیم را در حین ساخت یک متد جدید به عنوان پارامتری برای آن متد در نظر گرفت.

پیش از شروع آموزش، یک پروژه جدید تحت عنوان 38th Session به معنی "جلسه سی و هشتم" ایجاد کرده و کلاسی به نام MainClass به معنی "کلاس اصلی" در آن ایجاد می کنیم و به ادامه مطلب می رویم.

حال برای روشن شدن این مطلب نیاز به یک سناریو در دنیای واقعی داریم. فرض کنیم که پدر یا مادرمان از ما می خواهد که " برو به سوپر مارکت". در واقع ما بایستی کاری انجام دهیم. پس می توان این کار را به کاری که یک متد قرار است انجام دهد تشبیه کنیم. به عبارت دیگر اگر این درخواست پدر یا مادر خود را بخواهیم به یک متد در زبان برنامه نویسی جاوا تبدیل کنیم، متدی به شکل goToSuperMarket(); خواهیم داشت. حال در همان لحظه که آماده شده تا به سوپر مارکت برویم، از ما درخواست می شود که "راستی نون هم بخر". در این جا خرید نان به منزله اطلاعاتی اضافی است که در لحظه به دستور "برو به سوپر مارکت" الحاق می شود.

حال در این صورت متد فوق به شکل goToSuperMarket(bread); نوشته خواهد شد. در واقع خرید نان به عنوان پارامتری است که در لحظه به متد "برو به سوپر مارکت" اضافه شده و می بایست داخل پرانتز متد ما قرار گیرد. اکنون اگر والدین ما تصمیمشان عوض شود و به جای خرید نان از ما بخواهند که "راستی پنیر بخر" این پارامتر به پنیر تغییر کرده و متد ما به شکل goToSuperMarket(cheese); تغییر پیدا خواهد کرد. حال والدین ما ممکن است از ما بخواهند که هم نان بخریم و هم پنیر که در این صورت متد ما به شکل goToSuperMarket(bread, cheese); تغییر پیدا خواهد کرد.

اکنون ببینیم که استفاده از پارامترها در یک متد چه فایده ای دارد. در واقع با اضافه کردن یک پارامتر یا لیستی از پارامترها به یک متد، خواهیم توانست کارایی متد خود را افزایش دهیم. به عبارت دیگر به جای آنکه هر دفعه چیز یکسانی را دریافت کنیم(مثلا هر دفعه نان بگیریم)، می توانیم یک بار برای خرید نان به سوپر مارکت رفته، بار دیگر برای خرید پنیر به سوپر مارکت رفته و یا حتی بار دیگری برای خرید بستنی به سوپر مارکت برویم. در واقع زمانیکه ما متد خود را می نویسیم درهمان لحظه می توانیم تصمیم بگیریم که چه چیزی از سوپر مارکت نیاز داریم تا بخریم.

برای روشن تر شدن توضیحات فوق، قصد داریم تا این مفاهیم را در قالب یک پروژه جاوا بیان کنیم. برای این منظور کلاسی را که در ابتدای این آموزش ایجاد کردیم را به شکل زیر ویرایش می کنیم:

  1. public class MainClass {
  2. String mySentence = "Dear son go to supermarket";
  3. public void goToSuperMarket() {
  4. System.out.println(mySentence);
  5. }
  6. }
  7.  

در کد فوق ما یک کلاس از جنس String تحت عنوان mySentence به معنی "جمله من" داریم که Value در نظر گرفته شده برای آن عبارت Dear son go to supermarket به معنی "پسر عزیزم برو به سوپر مارکت" می باشد. سپس از متدی از جنس public تحت عنوان goToSuperMarket به معنی "به سوپر مارکت برو" ساخته ایم که قرار است هیچ گونه return یی نداشته باشد چرا که از جنس void است(در قسمت سی و نهم بیشتر پیرامون مبحث return صحبت خواهیم کرد). کاری که این متد قرار است انجام دهد این است که عبارت قرار گرفته در کلاس String را روی صفحه مانیتور به نمایش در آورد. اکنون می خواهیم پارامتر "یه چیزی هم بخر" را به متد خود اضافه کنیم. برای همین منظور کد فوق را به شکل زیر تکمیل می کنیم:

  1. public class MainClass {
  2. String mySentence = "Dear son go to supermarket";
  3. public void goToSuperMarket(String something) {
  4. System.out.println(mySentence);
  5. }
  6. }

همانطور که مشاهده می شود، داخل پرانتز متد خود یک پارامتر از جنس کلاس String تحت عنوان something به معنی "یه چیزی" اضافه کرده ایم. کاری که این پارامتر قرار است انجام دهد این است که در همان لحظه که متد فرا خوانده می شود کلاسی از جنس String تحت عنوان something به معنی "یه چیزی" را هم به عنوان پارامتر خود ارسال کند. حال برای آنکه این پارامتر هم در صفحه مانیتور به نمایش در آید، نیاز داریم تا آن را نیز در دستور System.out.println(); بگنجانیم. برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

  1. public class MainClass {
  2. String mySentence = "Dear son go to supermarket";
  3. public void goToSuperMarket(String something) {
  4. System.out.println(mySentence + something);
  5. }
  6. }

در این صورت، به محض اینکه این متد فرا خوانده شود هر آنچه مقداری که برای کلاس String تحت عنوان something در نظر گرفته شود نیز در پنجره Console به نمایش در خواهد آمد. حال می بایست این متد را فرا بخوانیم، برای این منظور یک کلاس جدید تحت عنوان ActionClass به معنی "کلاس عملیاتی" ایجاد کرده و از آنجا که این کلاس جدید قرار است به منزله نقطه شروع برنامه باشد پس نیاز داریم تا در حین ساخت آن گزینه public static void main را تیک بزنیم. حال کد ما می بایست به صورت زیر باشد:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4.  
  5. }
  6. }

اکنون در متد main در کلاس جدیدی که ایجاد کردیم یک شیئ از روی کلاس قبلی به صورت زیر می سازیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myShopping = new MainClass();
  5.  
  6. }
  7. }

در کد فوق ما نام کلاسی که می خواهیم از روی آن یک شیئ ایجاد کنیم را نوشته سپس نامی برای آن انتخاب کرده که در این مثال نام myShopping به معنی "خرید من" در نظر گرفته شده است. سپس یک علامت مساوی قرار داده کلید واژه new را می نویسیم و مجدداً نام کلاسی که می خواهیم شیئ مان از روی آن ساخته شود را می نویسیم و در نهایت یک علامت (); قرار می دهیم. شیئ ما ساخته شد. اکنون می خواهیم متدی که در کلاسی که از روی آن یک شیئ ساختیم را فرا بخوانیم. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myShopping = new MainClass();
  5. myShopping.goToSuperMarket();
  6.  
  7. }
  8. }

برای این منظور نام شیئ که جدیداً ساخته را نوشته سپس یک نقطه قرار داده و سپس نام متدی که در کلاس اصلی خود ساخته بودیم را می نویسیم و در نهایت علامت (); را در انتهای نام متد قرار می دهیم. به محض اینکه برنامه را Save کنیم، محیط برنامه نویسی اکلیپس از ما خطایی خواهد گرفت که در تصویر زیر قابل مشاهده است:

920610-j38-IMAGE 1.jpg

در واقع از آنجا که ما در متد خود یک پارامتر از جنس کلاس String تعریف کرده ایم ولیکن هیچ گونه مقداری برای آن پارامتر که از جنس کلاس String بود در نظر نگرفته ایم، همانطور که در باکس زرد رنگ در اولین خط آبی رنگ مشاهده می شود، اکلیپس به ما پیشنهاد می دهد که برای رفع این مشکل می بایست پارامتر از جنس String به متد goToSuperMarket اضافه کنیم. از آنجایی که این پارامتر از جنس کلاس String است و همانطور که می دانیم مقادیر این کلاس می بایست داخل دو علامت “ “ قرار گیرند، در متد فرا خوانده شده در شیئ ساخته شده صرفاً عبارتی را داخل دو علامت “ “ قرار داده و داخل پرانتز به شکل زیر می نویسیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myShopping = new MainClass();
  5. myShopping.goToSuperMarket(" and also buy some bread");
  6.  
  7. }
  8. }

همانطور که مشاهده می شود عبارت and also buy some bread به معنی "و همچنین مقداری نان بخر" داخل پرانتز نوشته شده است. حال برنامه خود را اجرا می کنیم(اگر توجه کنیم می بینیم که پیش از کلمه and یک فاصله قرار داده ایم. علت اینکار این است که می خواهیم دو جمله به یکدیگر نچسبند):

920610-j38-IMAGE 2.jpg

در تصویر فوق مشاهده می شود که String اول تحت عنوان mySentence در بخش اول به صورت Dear son go to supermarket به نمایش در آمده است. سپس پارامتر خود که از جنس String تحت عنوان something بود و در متدمان تعریف کردیم نیز به عبارت قبلی اضافه شده است. در واقع خوبی این پارامتر در اینجا است که فعلاً مقدار آن and also buy some bread می باشد اما این در حالی است که در لحظه پدر یا مادر ما می تواند نظرش را عوض کرده و از ما چیزی دیگر بخواهند که بخریم. به کد زیر توجه کنید:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myShopping = new MainClass();
  5. myShopping.goToSuperMarket(" and also buy some cheese");
  6.  
  7. }
  8. }

در کد فوق مقدار String را به جمله and also buy some cheese به معنی "و همچنین مقداری پنیر بخر" تغییر دادیم. حال مجدد برنامه را اجرا می کنیم:

920610-j38-IMAGE 3.jpg

می بینیم که در لحظه متد ما update شده و جمله جدید را نمایش می دهد. نکته ای که در اینجا حائز اهمیت است این است که نوع پارامتر تعیین شده برای متد بسیار تعیین کننده است که چه نوع داده ای به همراه آن متد در زمانیکه فرا خوانده می شود ارسال شود. در مثال فوق ما نوع داده را String قرار داده ایم. حال اگر نوع این داده متغیری از جنس int بود، می بایست داده ای از جنس عدد صحیح برای پارامتر متد خود در نظر بگیریم. نکته ای که در اینجا حائز اهمیت است این است که اگر ما بیش از یک پارامتر را برای متد خود در نظر بگیریم، حتما بایستی به همان ترتیبی که پارامترها را قرار داده ایم، مقادیر آن ها را وارد کنیم. به طور مثال اگر پارامتر اول ما از جنس String است و پارامتر دوم ما از جنس int است پس می بایست داده اولیه ما در حین فرا خواندن متد از جنس string بوده و داده دوم ما یک عدد صحیح باشد. در قسمت سی و نهم پیرامون مبحث return در زمانیکه متد ما پس از اجرا داده ای را به همراه خود باز می گرداند صحبت خواهیم کرد.

چهارشنبه 2 بهمن 1392  11:54 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت 39: آشنایی با دستور return در متدها


در قسمت سی و هشتم با نحوه ارسال یک پارامتر و تغییر آن در هر لحظه ای که تمایل داشتیم آشنا شدیم. در این قسمت قصد داریم تا مبحث return را مورد بررسی قرار دهیم. برای درک بهتر این موضوع بهتر است سناریویی که در قسمت پیشین در مورد رفتن به سوپر مارکت بیان کردیم را به خاطر آوریم. در واقع در آن مثال زمانیکه پدر یا مادرمان از ما درخواست کرد که به سوپر مارکت برویم و نان یا پنیر یا هر چیز دیگری بخریم هیچ گونه دستوری مبنی بر اینکه پس از خرید نان بلافاصله آن را به خانه بیاور وجود نداشت. در زبان برنامه نویسی جاوا در مورد متدها این دستور از طریق کلید واژه return انجام می شود.

سناریویی که در این قسمت از آموزش قصد داریم مطرح کنیم به این صورت است که فرض کنیم که ما برای برنامه نویسی از یک PC استفاده می کنیم و از آنجا که قصد داریم پروژه های خود را به موقع به پایان برسانیم نیاز به خرید یک لپ تاپ داریم تا همواره همراه ما باشد که بتوانیم حتی در زمان هایی هم که در منزل نیستیم روی پروژه خود کار کنیم. نکته ای که در اینجا وجود دارد این است که نمی دانیم کدام مدل لپ تاپ برای برای کار ما مناسب است که از قبل هزینه آن را تهیه کرده و همراه خود به خرید ببریم. برای این منظور به مرکز خرید کامپیوتر رفته و جستجوی خود را آغاز می کنیم.

به منظور درک بهتر این موضوع، پروژه ای جدید تحت عنوان 39th Session به معنی "جلسه سی و نهم" ایجاد کرده و کلاسی به اسم MainClass به معنی "کلاس اصلی" در آن می سازیم. حال کلاس اصلی خود را به شکل زیر آغاز می کنیم:

  1. public class MainClass {
  2.  
  3. public int goToComputerComplex() {
  4. int laptopPrice = 0;
  5. return laptopPrice;
  6. }
  7. }

در کد فوق یک متد از جنس int تحت عنوان goToComputerComplex به معنی "برو به مجتمع کامپیوتری" ایجاد کرده و متغیری از جنس int به نام laptopPrice به معنی "قیمت لپ تاپ" ایجاد کرده و مقدار اولیه آن را معادل با صفر قرار می دهیم. پیش از نام متد کلید واژه public دیده می شود که همانطور که قبلاً هم گفته شد به این معنا است که این متد از هر جای برنامه قابل دسترسی خواهد بود. هدف از ایجاد متغیر laptopPrice این است که هزینه خرید لپ تاپ به آن اختصاص داده شود و از سوی دیگر این متغیر یک Local Variable است و این بدان معنا است که این متغیر از هر جای دیگری خارج از متدی که داخل آن قرار گرفته است غیر قابل دسترسی خواهد بود. به طور کلی هر زمانیکه بخواهیم متد ما داده ای را بازگرداند یا اصطلاحاً return کند، نیاز است تا نوع متغیری که می خواهیم مقدار آن return شود را پیش از نام متد خود بنویسیم. به طور مثال اگر بخواهیم که متد ما یک عدد اعشاری را return کند پس بایستی متغیر double را نوشته و یا اگر بخواهیم مقدار بازگشتی متد ما یک داده از جنس true یا false باشد پس می بایست پیش از نام متد متغیری از جنس boolean بنویسیم. در این مثال از آنجا که می خواهیم داده ای از جنس int بازگردانده شود، پس کلید واژه int را قبل از نام متد خود می نویسیم(در حقیقت نام متغیر به جای کلید واژه void قرار خواهد گرفت). اکنون نیاز داریم تا متد خود را از داخل کلاس دیگری فرا بخوانیم. برای همین منظور یک کلاس جدید تحت عنوان ActionClass به معنی "کلاس عملیاتی" ایجاد کرده و از آنجا که می خواهیم این کلاس به منزله نقطه شروع برنامه باشد، در حین ساخت آن گزینه public static void main را تیک می زنیم. حال کد کلاس ما می بایست به شکل زیر باشد:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4.  
  5. }
  6. }

هم اکنون نیاز است تا یک شیئ از روی کلاس MainClass داخل کلاس ActionClass ایجاد کنیم. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myObject = new MainClass();
  5. }
  6. }

همانطور که قبلاً آموزش داده شد یک شیئ جدید تحت عنوان myObject به معنی "شیئ من" از روی کلاس MainClass ایجاد می کنیم. حال با این کار به متد ساخته شده در کلاس MainClass هم دسترسی خواهیم داشت. همانطور که قبلا گفته شد، متد goToComputerComplex داده ای را return خواهد کرد که جنس آن داده int است. از این رو یک متغیر جدید در کلاس ActionClass تحت عنوان totalPrice به معنی "قیمت کل" ایجاد کرده و مقدار آن را برابر با متد goToComputerComplex قرار می دهیم. حال کد ما می بایست به شکل زیر باشد:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myObject = new MainClass();
  5. int totalPrice = myObject.goToComputerComplex();
  6. }
  7. }

به طور خلاصه هر مقداری که برای متغیر laptopPrice در متد goToComputerComplex واقع در کلاس MainClass در نظر گرفته شود، حال به متغیر totalPrice که در کلاس ActionClass قرار دارد return خواهد شد. اکنون برای آنکه بتوانیم مقدار return شده را روی صفحه مانیتور مشاهده کنیم، نیاز است تا از دستور System.out.println(); استفاده کنیم. بنابراین کد ما به شکل زیر در خواهد آمد:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MainClass myObject = new MainClass();
  5. int totalPrice = myObject.goToComputerComplex();
  6. System.out.println("The price of my laptop is: " + totalPrice);
  7. }
  8. }

همانطور که در کد فوق مشاهده می شود، دستور System.out.println(); را نوشته و چیزی را که می خواهیم روی صفحه مانیتور به نمایش در آید را داخل پرانتز آن قرار می دهیم. از آنجا که در این مثال می خواهیم مقدار متغیر totalPrice که به عبارتی همان مقدار return شده متغیر laptopPrice است را نمایش دهیم، پس نام totalPrice را داخل پرانتز می نویسیم. از آنجا که می خواهیم بدانیم که این مقدار نمایش داده شده متعلق به چیست، پیش از نام این متغیر عبارت The price of my laptop is: به معنی "قیمت لپ تاپ من معادل است با:" را که یک string است به آن اضافه می کنیم. حال پس از اجرای برنامه خروجی زیر مشاهده خواهد شد:

920610-a39-IMAGE 1.jpg

همانطور که در تصویر فوق مشاهده می شود برنامه به درستی کار کرده و مقدار return شده که هم اکنون معادل با صفر است را در کلاس ActionClass نمایش می دهد. حال مقدار return شونده را در کلاس MainClass را به عدد 2800000 تغییر می دهیم:

  1. public class MainClass {
  2.  
  3. public int goToComputerComplex() {
  4. int laptopPrice = 2800000;
  5. return laptopPrice;
  6. }
  7. }

حال مجدد برنامه را اجرا می کنیم:

920610-a39-IMAGE 2.jpg

همانطور که ملاحظه می شود، به محض تغییر مقدار متغیر، مقدار return شونده از سوی متد goToComputerComplex نیز تغییر پیدا می کند. اکنون که قیمت لپ تاپ نهایی شد، اگر خود سر کار می رویم که می بایست به حساب بانکی مان رجوع کنیم و در غیر این صورت این مقدار return شده را به شماره همراه یکی از والدین خود مجدد return می کنیم تا این مبلغ را برای ما واریز کنند!

چهارشنبه 2 بهمن 1392  11:55 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۴۰: تفاوت میان Local Variable ها و Field ها


پس از آشنایی با مفهوم متد به طور کلی در آموزش های سی و هفتم، سی و هشتم و سی و نهم، حال نوبت به بررسی مفهوم Constructor ها در زبان برنامه نویسی جاوا می رسد اما پیش از آشنایی با Constructor ها لازم است تا تفاوت مابین Field Variable ها و Local Variable ها را درک کرده باشیم.

برای همین منظور پروژه ای تحت عنوان 40th Session به معنی "جلسه چهلم" در محیط اکلیپس ایجاد کرده و کلاسی تحت عنوان Constructor در آن می سازیم. اکنون کد برنامه می بایست به صورت زیر باشد:

  1. public class Constructor {
  2.  
  3. }

به طور کلی چنانچه ما متغیری را داخل یک متد تعریف کنیم، آن متغیر یک Local Variable خواهد بود. به عبارت دیگر فقط قابل دسترسی داخل آن متد بوده و متدهای دیگر نمی توانند آن متغیر را مورد استفاده قرار دهند. برای روشن شدن مطلب به مثال زیر توجه کنید:

  1. public class Constructor {
  2. public void testMethodOne() {
  3. int number;
  4. }
  5.  
  6. }

در کد فوق ما یک متد تحت عنوان testMethodOne داریم که دارای متغیری از جنس int تحت عنوان number به معنی "عدد" است. در حقیقت متغیر int یک Local Variable یا به عبارتی یک متغیر داخلی است و فقط متد testMethodOne به آن دسترسی خواهد داشت. از سوی دیگر اگر یک کلاس جدید ایجاد کنیم که از کلاس Constructor ارث بری کند، سپس یک شیئ از روی کلاس Constructor در آن بسازیم، صرفا ما به خود متد testMethodOne دسترسی خواهیم داشت و نخواهیم توانست کنترل متغیر int داخل این متد را به صورت اختصاصی در دست بگیریم. برای روشن شدن این مطلب یک کلاس دیگر تحت عنوان ActionClass به معنی "کلاس عملیاتی" ایجاد می کنیم که از کلاس Constructor ارث بری می کند. سپس یک شیئ از روی کلاس Constructor تحت عنوان objectOne به معنی "شیئ یک" می سازیم. حال کد ما می بایست به صورت زیر باشد:

  1. public class ActionClass extends Constructor {
  2. public static void main(String[] args) {
  3. Constructor objectOne = new Constructor();
  4.  
  5. }
  6. }

حال می خواهیم تا به متغیر داخل متد testMethodOne که داخل کلاس Constructor ایجاد کرده است دست یابیم. برای این منظور نام شیئ ایجاد شده از روی کلاس Constructor که همان objectOne است را نوشته سپس یک نقطه قرار می دهیم:

921706-j40-IMAGE 1.jpg

همانطور که در تصویر فوق مشاهده می شود، به محض اینکه یک نقطه پس از نام شیئ ایجاد شده قرار می دهیم، نرم افزار اکلیپس به صورت خودکار نام چیزهایی که برای این شیئ قابل دسترسی هستند را برای ما داخل پنجره ای نمایش می دهد. همانطور که فلش قرمز رنگ نشان می دهد، از کلاس Constructor ما فقط به متد testMethodOne دسترسی داریم و به هیچ وجه متغیر int که داخل آن متد قرار داده ایم در لیست چیزهایی که به آن دسترسی داریم وجود نخواهد داشت. حال اگر متغیری را خارج از یک متد تعریف کنیم، این متغیر به مثابه یک Field Variable خواهد بود. به عبارت دیگر از دیگر بخش های برنامه نیز قابل دسترسی خواهد بود. برای روشن شدن مطالب فوق کد خود را به شکل زیر بازنویسی می کنیم:

  1. public class Constructor {
  2. int number;
  3. public void testMethodOne() {
  4.  
  5. }
  6. }

در کد فوق ما یک متغیر از جنس int داریم که داخل خود کلاس تعریف شده است. به عبارت دیگر این متغیر برای کلیه متدهای داخل کلاس ما قابل دسترسی خواهند بود. برای روشن شدن این مطلب، مجدداً به کلاس دومی که ساختیم باز می گردیم. این بار به محض اینکه نام شیئ ساخته شده از روی کلاس Constructor را می نویسیم و یک نقطه قرار می دهیم، می بینیم که علاوه بر متد testMethodOne نرم افزار اکلیپس متغیری تحت عنوان number که در کلاس Constructor ساخته شده است را نیز نشان می دهد:

921706-j40-IMAGE 2.jpg

در حقیقت این مسئله نشانگر این است که متغیرهایی از جنس Field یا به عبارت دیگر هر متغیری که در خود کلاس تعریف شود، برای دیگر بخش های برنامه نیز قابل دسترسی خواهد بود. نکته دیگری که در مورد Field ها همواره می بایست مد نظر داشته باشیم این است که ما به هر تعداد که بخواهیم می توانیم از آن ها در دیگر جاهای برنامه خود استفاده کنیم و این در حالی است که مقدار در نظر گرفته شده برای آن ها مخصوص همان اشیائی است که از آن Field استفاده می کنند. برای روش شدن مطلب به مثال زیر توجه کنید:

  1. public class ActionClass extends Constructor {
  2. public static void main(String[] args) {
  3. Constructor objectOne = new Constructor();
  4. objectOne.number = 12;
  5.  
  6. Constructor objectTwo = new Constructor();
  7. objectTwo.number = 20;
  8.  
  9. }
  10. }

همانطور که در کد فوق ملاحظه می شود، ما دو شیئ از روی کلاس Constructor ساخته ایم که شیئ اول objectOne و شیئ دوم objectTwo نام دارد. سپس از طریق شیئ اول به Field ساخته شده تحت عنوان number دسترسی پیدا کرده و مقدار آن را معادل با 12 قرار می دهیم. در نهایت از طریق شیئ دوم هم به این Field دسترسی پیدا کرده و مقدار آن را معادل با 20 قرار می دهیم. همانطور که ملاحظه می شود، این دو Value متفاوت با یکدیگر تناقضی ندارند چرا که در هر شیئ ساخته شده از روی کلاس Constructor به طور مجزا مورد استفاده قرار گرفته اند. شاید به همین دلیل باشد که نام دیگری که برای متغیرهای Field در نظر گرفته شده است Instance Variable است. به عبارت دیگر متغیری که در هر Instance یا "نمونه" ای از یک کلاس مورد استفاده قرار می گیرد. اکنون به نظر می رسد با درک کامل تفاوت مابین Local Variable ها و Field ها بهتر بتوانیم به مبحث Constructor ها در زبان برنامه نویسی جاوا بپردازیم. چنانچه بخواهیم به طور خلاصه بگوییم که Constructor چیست، بایستی گفت که یک Constructor همانند یک متد است با این تفاوت که نام آن دقیقاً با نام کلاس یکی بوده و از سوی دیگر به هیچ وجه نمی تواند داده ای را return کند. واقعیت دیگری که در مورد Constructor ها صدق می کند این است که یک Constructor می تواند هیچ پارامتری نداشته باشند، یک پارامتر داشته و یا حتی بیش از یک پارامتر داشته باشد. اکنون که با مقدمه ای کوتاه با مفهوم Constructor ها آشنا شدیم خواهیم توانست در آموزش بعد درک بهتری از این ساختار داشته باشیم.

چهارشنبه 2 بهمن 1392  11:57 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۴۱ : Constructor ها در زبان جاوا


به نظر می رسد پس از آشنایی با تفاوت مابین Local Variable ها و Field ها در زبان جاوا بتوانیم بهتر مفهوم Constructor ها را در زبان برنامه نوسی جاوا درک کنیم. برای همین منظور پروژه ای تحت عنوان 41st Session به معنی "جلسه چهلم و یکم" در محیط اکلیپس ایجاد کرده و کلاسی تحت عنوان MyClass به معنی "کلاس من" در آن می سازیم و به ادامه مطلب می رویم.

چنانچه بخواهیم به طور خلاصه بگوییم که Constructor چیست، بایستی گفت که یک Constructor همانند یک متد است با این تفاوت که نام آن دقیقاً با نام کلاس یکی بوده و از سوی دیگر به هیچ وجه نمی تواند داده ای را return کند(به منظور آشنایی با دستور return به آموزش سی و هشتم مراجعه فرمایید). واقعیت دیگری که در مورد Constructor ها صدق می کند این است که یک Constructor می تواند هیچ پارامتری نداشته باشند، یک پارامتر داشته و یا حتی بیش از یک پارامتر داشته باشد.

اکنون ببینیم که کاربرد یک Constructor چیست. در واقع زمانیکه ما یک شیئ از روی کلاس خود می سازیم، Constructor آن کلاس فرا خوانده می شود. کار این Constructor این است که Field های آن شیئ جدید را Initialize کرده یا به عبارت دیگر آغاز کند. نکته ای که در اینجا می بایست حتما مد نظر قرار داده شود این است که ما برای ساخت یک شیئ جدید از روی یک کلاس نیاز به یک Constructor داریم و اگر ما این Constructor را ننویسیم، خود Compiler در حین ساخت شیئ جدید یک Constructor که فاقد هرگونه پارامتری باشد را برای ما در حین Compile شدن خواهد ساخت. این Constructor تحت عنوان Default Constructor یا Constructor پیش فرض شناخته می شود. کاری که این Constructor انجام می دهد این است که کلیه متغیرهای Field را با مقدار اولیه Default فرا می خواند(مقدار اولیه صفر برای متغیرهای عددی، مقدار false برای متغیر boolean و مقدار null برای مواردی همچون string ).

حال اگر ما یک Constructor برای کلاس خود طراحی کنیم Compiler هیچ گونه Constructor یی از جنس default به صورت خودکار نخواهد ساخت و Constructor ما را مورد استفاده قرار می دهد.

اکنون کد موجود در کلاس خود را به شکل زیر تکمیل می کنیم:

  1. public class MyClass {
  2. String name;
  3. int age;
  4. boolean trueOrFalse;
  5.  
  6. public void dispaly() {
  7. System.out.println(name);
  8. System.out.println(age);
  9. System.out.println(trueOrFalse);
  10. }
  11. }

در کد فوق همانطور که مشاهده می شود سه Instance Variable یا متغیرهای Field یکی از جنس متغیر عددی، یکی از جنس متغیر boolean و یکی هم از جنس کلاس String تحت عناوین name و age و trueOrFalse به معنی به ترتیب "نام، سن و درست یا غلط" ساخته ایم. سپس یک متد تحت عنوان display به معنی "نمایش بده" ساخته و در آن دستور داده ایم تا Field های ایجاد شده در داخل کلاس را روی صفحه مانیتور نمایش دهد. حال نوبت به ساخت کلاس دیگری می رسد که به منزله نقطه شروع برنامه باشد. به عبارت دیگر این کلاس جدید می بایست دارای متد main باشد. برای این منظور کلاس دیگری تحت عنوان ActionClass به معنی "کلاس عملیاتی" ساخته و در حین ساخت آن گزینه public static void main را تیک می زنیم. پس از ساخت این کلاس، یک شیئ از روی کلاس MyClass ساخته و نام آن را object به معنی "شیئ" می گذاریم و در نهایت از طریق شیئ ساخته شده متد موجود در کلاس MyClass را فرا می خوانیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MyClass objectOne = new MyClass();
  5. objectOne.dispaly();
  6. }
  7. }

حال برنامه خود را اجرا می کنیم:

920623-j41-IMAGE 1.jpg

همانطور که در تصویر فوق مشاهده می شود، Compiler به صورت خودکار یک Default Constructor برای شیئ ساخته شده ما از روی کلاس MyClass ایجاد می کند و همانطور که قبلا گفته شد کار این Constructor این است که مقادیر پیش فرض را برای Field های کلاس MyClass را ایجاد کند(البته این Constructor از آنجا که در حین Compile شدن ساخته می شود از دید ما مخفی است). در تصویر فوق مقدار پیش فرض null برای کلاس String بوده، مقدار پیش فرض صفر برای متغیر int بوده و مقدار پیش فرض آخر که معادل با false است برای متغیر boolean می باشد. در حقیقت خود Compiler جاوا این Constructor را برای شیئ ما ساخته است. حال ببینیم Compiler به چه شکلی این Constructor را در کلاس ما ایجاد کرده است. برای این منظور کد کلاس MyClass را به شکل زیر تکمیل می کنیم:

  1. public class MyClass {
  2. String name;
  3. int age;
  4. boolean trueOrFalse;
  5.  
  6. MyClass() {
  7. name = null;
  8. age = 0;
  9. trueOrFalse = false;
  10. }
  11.  
  12. public void dispaly() {
  13. System.out.println(name);
  14. System.out.println(age);
  15. System.out.println(trueOrFalse);
  16. }
  17. }

همانطور که در کد فوق مشاهده می شود، یک Constructor تحت عنوان MyClass(){} ساخته ایم(همانطور که در بالا گفته شده نحوه ساخت Constructor همانند ساخت یک متد است با تفاوت که نام آن می بایست دقیقاً هم نام با کلاس بوده و هیچ گونه مقدار بازگشتی مثل int و double وString و غیره نمی بایست برای آن تعریف شود). اکنون داخل Constructor ساخته شده برای Field های کلاس خود مقدار اولیه تعریف می کنیم. مقدار Default برای string ها همواره null بوده، برای متغیرهای عددی مثل int همواره صفر بوده و برای متغیر boolean معادل با false می باشد. به طور خلاصه نوشتن و ننوشتن این Constructor هیچ فرقی برای ما نخواهد کرد چرا که Compiler این کار را به عهده گرفته است. به عبارت دیگر اگر ما برای شیئ جدیدی که می سازیم مقادیر اولیه در نظر نگیریم، Compiler در حین Compile کردن برنامه این کار را به صورت خودکار برای ما انجام خواهد داد(این کار در تصویر زیر نشان داده شده است).

920623-j41-IMAGE 2.jpg

برای این که تست کنیم که Compiler این کار را به صورت خودکار انجام می دهد یا خیر می توان Constructor ساخته شده را Comment کرده و برنامه را مجدد اجرا کنیم و خواهیم دید که بازهم همان مقادیر اولیه توسط Compiler ایجاد می شوند. هم اکنون می خواهیم تا دیگر به Compiler اجازه ندهیم تا مقادیر Default را برای Field ها در نظر گیرد، بلکه خود این مقادیر را تعریف کنیم. برای این منظور کد کلاس MyClass را به شکل زیر تغییر می دهیم:

  1. public class MyClass {
  2. String name;
  3. int age;
  4. boolean trueOrFalse;
  5.  
  6. MyClass(String myName, int myAge, boolean myTrueOrFalse) {
  7. name = myName;
  8. age = myAge;
  9. trueOrFalse = myTrueOrFalse;
  10. }
  11.  
  12. public void dispaly() {
  13. System.out.println(name);
  14. System.out.println(age);
  15. System.out.println(trueOrFalse);
  16. }
  17. }

همانطور که در کد فوق ملاحظه می شود، سه پارامتر دقیقا از همان جنسی که Field ها هستند برای Constructor در نظر گرفته ایم به نام های myName, myAge, myTrueOrFalse و هر کدام از آن ها را معادل با هم تای خود که از جنس Field است قرار داده ایم. علت اینکه نام پارامترهای Constructor خود را با نام Field های یکی قرار نداده ایم این است که اگر هر دو نام یکی باشد، Compiler در حین Compile کردن مقادیر Field ها را مد نظر قرار خواهد داد. کد فوق بدون هیچ مشکلی اجرا خواهد شد اما این در حالی است که راه کاری برای اینکه نام پارامترها و Field ها یکی باشد نیز وجود دارد و آن هم استفاده از کلید واژه this می باشد. برای درک بهتر این موضوع کد فوق را به شکل زیر بازنویسی می کنیم:

  1. public class MyClass {
  2. String name;
  3. int age;
  4. boolean trueOrFalse;
  5.  
  6. MyClass(String name, int age, boolean trueOrFalse) {
  7. this.name = name;
  8. this.age = age;
  9. this.trueOrFalse = trueOrFalse;
  10. }
  11.  
  12. public void dispaly() {
  13. System.out.println(name);
  14. System.out.println(age);
  15. System.out.println(trueOrFalse);
  16. }
  17. }

همانطور که ملاحظه می شود کلید واژه this را قرار داده سپس یک نقطه می گذاریم و نام پارامتر مد نظر را پس از نقطه قرار می دهیم و در نهایت یک علامت مساوی قرار داده و نام Field خود را پس از آن می نویسیم و در انتها یک علامت ; قرار می دهیم. با این کار به Compiler دستور می دهیم که مثلا this.name منظور name یی است که پارامتر است و یا this.age منظور از age همان age یی است که داخل پارامتر متد نوشته شده است نه age یی که به عنوان متغیر Field در نظر گرفته شده است. از سوی دیگر نام های name, age, trueOrFalse که پس از علائم مساوی قرار گرفته اند همان Field هایی هستند که برای کلاس MyClass در نظر گرفته ایم. اکنون پس از آنکه مقدار Field های کلاس MyClass را از طریق یک Constructor که خودمان ایجاد کرده ایم را به پارامتر ها نسبت داده ایم می توانیم برنامه خود را اجرا کنیم. برای همین منظور به کلاس ActionClass رفته و کد خود را به شکل زیر تکمیل می کنیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MyClass objectOne = new MyClass("behzad", 29, true);
  5. objectOne.dispaly();
  6. }
  7. }

اگر خاطرمان باشد در کلاس MyClass زمانیکه Constructor خود را ایجاد می کردیم سه پارامتر به ترتیب از جنس String و int و boolean ایجاد کردیم. حال در کلاس ActionClass با قرار دادن مقادیری داخل پرانتزها متناظر با جایگاه پارامترها(یعنی اول یک داده از جنس string و دوم یک داده از جنس متغیر int و سوم یک داده از جنس boolean )، می توانیم مقدار اولیه پارامترها را تعیین کرده و بالتبع از آنجا که مقدار پارامترها برابر با مقدار Field ها در نظر گرفته شده است، از این رو مقدار اولیه Field ها تعیین خواهد شد(به طور خلاصه همانطور که در کد فوق مشاهده می شود مقدار “Behzad” برای پارامتری از جنس string تحت عنوان name در نظر گرفته شده است و از آنجا که مقدار Field یی تحت عنوان name برابر با this.name یا همان پارامتری که از جنس string است قرار داده شده است، پس مقدار “Behzad” به Field کلاس MyClass تحت عنوان name که از جنس کلاس String است اختصاص خواهد یافت. دو پارامتر دیگر را نیز به همین شکل می توان تفسیر کرد). پس از اجرای برنامه خروجی زیر مشاهده خواهد شد:

920623-j41-IMAGE 3.jpg

همانطور که می بینیم با موفقیت توانستیم مقدار اولیه Field های کلاس اول را مقدار دهی کنیم. اکنون فرض کنیم که از روی کلاس MyClass دو عدد شیئ داریم، یکی تحت عنوان objectOne و دیگری تحت عنوان objectTwo . برای مقدار دهی هر دوی آن ها کد خود را به شکل زیر تکمیل می کنیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. MyClass objectOne = new MyClass("behzad", 29, true);
  5. objectOne.dispaly();
  6.  
  7. MyClass objectTwo = new MyClass("Mohammad Ali", 31, false);
  8. objectTwo.dispaly();
  9. }
  10. }

همانطور که مشاهده می شود در کد فوق دو شیئ از روی کلاس MyClass تحت عناوین objectOne و objectTwo به معنی به ترتیب "شیئ یک" و "شیئ دو" ساخته ایم. از آنجا که می خواهیم شیئ دوم ما هم دارای مقادیر اولیه ای باشد، سه پارامتر با مقادیر Mohammad Ali و 31 و false را برای آن در نظر می گیریم. حال برنامه را اجرا می کنیم:

920623-j41-IMAGE 4.jpg

همانطور که در تصویر فوق مشاهده می شود هر دو شیئ ساخته شده از روی کلاس MyClass با مقادیر اختصاصی خودشان در پنجره Console نمایش داده شده اند.

چهارشنبه 2 بهمن 1392  11:58 AM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۴۲: آشنایی با دستور super در بحث وراثت در زبان برنامه نویسی


یکی از مباحثی که تسلط به آن در رابطه با به کار گیری وارثت در زبان برنامه نویسی جاوا ضروری است نحوه به کارگیری کلید واژه super است. چنانچه بخواهیم به طور خلاصه کاربرد کلید واژه super را بیان کنیم، بایستی گفت که هر موقع که بخواهیم در کلاسهای Subclass یک متد، متغیر و یا Constructor را در Superclass فرا بخوانیم می بایست از کلید واژه super استفاده کنیم. برای روشن شدن اهمیت این کلید واژه به توضیحات بیشتر در قالب یک پروژه خواهیم پرداخت.

ادامه مطلب را از دست ندهید.

پروژه جدیدی در اکلیپس تحت عنوان 42nd Session به معنی "جلسه چهل و دوم" ایجاد کرده و دو کلاس به اسم های SuperClass و SubClass به معنی به ترتیب "کلاس اصلی" و "کلاس زیرشاخه" در آن می سازیم. برای کلاسی که قرار است به منزله نقطه شروع برنامه باشد نام ActionClass به معنی "کلاس عملیاتی" را در نظر گرفته و گزینه public static void را برای آن تیک دار می کنیم.

در این مرحله نیاز است تا کلاس SuperClass را به شکل زیر تکمیل نماییم:

  1. public class SuperClass {
  2. int speed = 280;
  3. public void showLexusSpeed() {
  4. System.out.println("Lexus speed is " + speed);
  5. }
  6. }

در کد فوق در کلاس SuperClass یک Instance Variable از جنس int تحت عنوان speed به معنی "سرعت" ایجاد کرده ایم و مقدار اولیه آن را معادل با 280 قرار داده ایم(منظور 280 کیلومتر در ساعت است) سپس یک متد از جنس void تحت عنوان showLexusSpeed به معنی "سرعت لکسوس را نمایش بده" ایجاد کرده ایم. در نهایت با استفاده از دستور System.out.println(); می خواهیم مقدار متغیر speed را روی صفحه مانیتور نمایش دهیم. در این دستور علاوه بر نشان دادن مقدار متغیر speed می خواهیم جمله Lexus speed is به معنی "سرع لکسوس برابر است با ..." هم نشان داده شود. برای همین منظور این جمله را داخل دو علامت “ “ نوشته و یک علامت به علاوه قرار داده سپس نام متغیر خود را می نویسیم. اکنون نوبت به تکمیل کد کلاس SubClass می رسد که می بایست به شکل زیر عمل کنیم:

  1. public class SubClass extends SuperClass {
  2. int speed = 260;
  3. public void showToyoTaSpeed() {
  4. System.out.println("Toyota speed is "+speed);
  5. }
  6. }

همانطور که در کد فوق مشاهده می شود، کلاس SubClass از کلاس SuperClass ارث بری خواهد کرد(این کار با استفاده از کلید واژه extends به علاوه نام کل SuperClass صورت می گیرد). مجدد یک متغیر از جنس int تحت عنوان speed ایجاد کرده ولی این بار مقدار اولیه 260 را برای آن در نظر می گیریم. متد ساخته شده در این کلاس showToyotaSpeed به معنی "سرعت تویوتا را نشان بده" می باشد. در نهایت همانند کلاس قبلی از دستور System.out.println(); استفاده می کنیم تا مقدار متغیر speed را به علاوه جمله Toyota speed is به معنی "سرعت تویوتا برابر است با ..." روی صفحه مانیتور نمایش دهیم. اکنون می خواهیم از روی این کلاس یک شیئ ساخته و آن را در متد main در کلاس ActionClass نمایش دهیم. برای همین منظور کلاس ActionClass را به شکل زیر تکمیل می کنیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. SubClass myObject = new SubClass();
  5. myObject.showToyoTaSpeed();
  6. }
  7. }

همانطور که در کد فوق مشاهده می شود یک شیئ جدید از روی کلاس SubClass به نام myObject به معنی "شیئ من" ساخته، سپس با استفاده از این شیئ جدید متد موجود در داخل کلاس SubClass را فرا می خوانیم. حال برنامه را اجرا می کنیم:

920625-j42-IMAGE1.jpg

همانطور که در تصویر فوق مشاهده می شود برنامه متد showToyotaSpeed را فراخوانده و خروجی آن را در پنجره Console نمایش می دهد. نکته ای که در اینجا می بایست مد نظر قرار داده شود این است هم در کلاس SuperClass و هم در کلاس SubClass ما متغیر speed را نوشته ایم. در اجرای فوق علیرغم اینکه کلاس SubClass از کلاس SuperClass ارث بری می کند، اما این در حالی است که شیئ ساخته شده در آن از متغیر موجود داخل SubClass استفاده می کند و نتیجه این می شود که سرعت 260 کیلومتر در ساعت برای خودروی تویوتا در نظر گرفته می شود. حال فرض کنیم می خواهیم از عمد کاری کنیم که مقدار متغیر speed موجود در کلاس SuperClass در متد فراخوانده شود. برای این منظور کد خود در داخل متد SubClass را به شکل زیر ویرایش می کنیم:

  1. int speed = 260;
  2. public void showToyoTaSpeed() {
  3. System.out.println("Toyota speed is " + super.speed);
  4. }
  5. }

همانطور که در کد فوق ملاحظه می شود، قبل از speed از کلید واژه super به علاوه یک نقطه استفاده کرده ایم. حال مجدداً برنامه را اجرا می کنیم:

920625-j42-IMAGE2.jpg

می بینیم که کلید واژه super این دستور را به برنامه می دهد که بایستی برود از متغیر موجود در کلاس اصلی استفاده کند. بنابراین مقدار 280 کیلومتر در ساعت برای خودروی تویوتا در نظر گرفته می شود. اکنون ببینیم که به چه نحوی می توان از کلید واژه super برای متدها استفاده کرد. برای روشن شدن مطلب کد کلاس SuperClass را به شکل زیر بازنویسی می کنیم:

  1. public class SuperClass {
  2.  
  3. public void showSuperClass() {
  4. System.out.println("This is the SuperClass method");
  5. }
  6. }

در کد فوق یک متد تحت عنوان showSuperClass به معنی "کلاس اصلی را نشان بده" ساخته و وظیفه این متد آن است که عبارت This is the SuperClass method به معنی "این متد کلاس اصلی است" را نمایش دهد. سپس به صورت زیر اقدام با بازنویسی کلاس SubClass می کنیم:

  1. public class SubClass extends SuperClass {
  2.  
  3. public void showSubClass() {
  4. System.out.println("This is the SubClass method");
  5. }
  6. }

در کد فوق یک متد تحت عنوان showSubClass به معنی "کلاس زیرمجموعه را نشان بده" ساخته و به آن دستور داده ایم تا عبارت This is the SubClass method را معنی "این متد کلاس زیر مجموعه است" را نمایش دهد. در نهایت کد کلاس ActionClass را به شکل زیر بازنویسی می کنیم:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. SubClass myObject = new SubClass();
  5. myObject.showSubClass();
  6. }
  7. }

حال قصد داریم تا به برنامه خود دستور دهیم تا شیئ ساخته شده ما تحت عنوان myObject متد موجود در کلاس زیرمجموعه را تحت عنوان showSubClass را روی صفحه مانیتور نمایش دهد. حال برنامه را اجرا کرده و می بایست خروجی زیر را مشاهده نماییم:

920625-j42-IMAGE3.jpg

همانطور که انتظار می رفت هر دستوری که داخل متد showSubClass می باشد اجرا شده است. حال اگر بخواهیم با استفاده از کلید واژه super متد خود را مجبور کنیم تا متد موجود در کلاس اصلی را نیز نمایش دهد، می بایست کد کلاس زیر مجموعه را به شکل زیر تکمیل نماییم:

  1. public class SubClass extends SuperClass {
  2.  
  3. public void showSubClass() {
  4. System.out.println("This is the SubClass method");
  5. super.showSuperClass();
  6. }
  7. }

در حقیقت با نوشتن کلید واژه super و قرار دادن یک نقطه و نوشتن نام متدی از کلاس اصلی که می خواهیم نمایش داده شود، برنامه خود را مجبور می کنیم تا اینکار انجام دهد. اکنون برنامه را مجدد Run می کنیم و انتظار می رود که خروجی زیر ایجاد گردد:

920625-j42-IMAGE4.jpg

همانطور که مشاهده می شود علاوه بر متد موجود در کلاس SubClass متد موجود در کلاس SuperClass نیز با استفاده از دستور super فرا خوانده شده است.

چهارشنبه 2 بهمن 1392  12:07 PM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت 43: پروژه محاسبه مصرف سوخت خودرو با استفاده از Constructor ها


پس از آشنایی با مفهوم Constructor ها در قسمت چهل و یکم، به منظور درک عملی Constructor ها سناریویی تعریف کرده و به طور عملی این نوع از متدها را مورد استفاده قرار می دهیم. فرض کنیم که می خواهیم برنامه ای طراحی کنیم که در ابتدا نام ما را گرفته سپس نام خودروی خود را وارد برنامه کرده، در نهایت این برنامه به ما می گوید میزان مصرف خودروی ما در هر صد کیلومتر چند لیتر است.

برای شروع کار یک پروژه جدید تحت عنوان 43rd Session به معنی "جلسه چهل و سوم" ایجاد می کنیم و کلاسی به نام FuelConsomption به معنی "مصرف سوخت" در آن تعریف می کنیم. اکنون پیش از شروع هر کاری اقدام به ایجاد دو Field در کلاس خود تحت عناوین نام، نام خودرو می کنیم:

  1. public class FuelConsumption {
  2. String name;
  3. String carName;
  4.  
  5. }

همانطور که در کد فوق ملاحظه می شود Field اول که از جنس String است name به معنی "نام" نامیده شده است که قرار است نام صاحب خودرو را در خود ذخیره سازد. سپس یک Field دیگر از همین جنس تحت عنوان carName به معنی "نام خودرو" ایجاد کرده ایم که نام خودروی ما را قرار است در خود ذخیره سازد. اکنون نیاز است تا یک Constructor تعریف کنیم که مقادیر اولیه این Field ها را مشخص سازد. برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

  1. public class FuelConsumption {
  2. String name;
  3. String carName;
  4.  
  5. // Constructor
  6. public FuelConsumption(String name, String carName) {
  7. this.name = name;
  8. this.carName = carName;
  9. }
  10. }

همانطور که در کد فوق ملاحظه می شود یک Comment قرار داده ایم که بدانیم کد بعد از آن مربوط به Constructor است. سپس Constructor خود را به گونه ای تعریف کرده ایم که می بایست برای اجرا، دو پارامتر ورودی آن مشخص شوند. به عبارت دیگر مادامیکه کاربر نام و نام خودروی خود را وارد برنامه نکند، شیئ ساخته شده از روی کلاس FuelConsumption کار نخواهد کرد. کاری که در این برنامه انجام داده ایم این است که نام پارامترهای Constructor خود را هم نام Field ها در نظر گرفته ایم(لازم به ذکر است که برای پارامترها هر نامی می توان در نظر گرفت اما از آنجا که می خواهیم تعداد نام های متغیرهای برنامه ما به حداقل برسد، این نام ها را هم نام با نام Field ها در نظر گرفته ایم). زمانیکه نام پارامترها با نام Field ها یکی باشد، Compiler در حین اجرا مقادیر Field ها را مد نظر قرار خواهد داد. برای رفع این مشکل از کلید واژه this استفاده می کنیم. همانطور که در کد فوق ملاحظه می شود پیش از name از کلید واژه this به علاوه یک نقطه استفاده شده و در نهایت یک علامت مساوی قرار داده ایم و مجدد واژه name را نوشته و یک علامت ; پس از آن قرار داده ایم. به زبان ساده این بدان معنا است که "این" پارامتری که نام آن name است، مقدار آن برابر با Field یی است که نام آن name می باشد. در مورد carName هم شرایط به همین صورت است. از آنجا که نیاز است مقدار بازگشتی این Field ها بارها در برنامه ما مورد استفاده قرار گیرند، از این رو دو متد با قابلیت return برای هر یک از Field ها به صورت زیر تعریف می کنیم:

  1. public class FuelConsumption {
  2. String name;
  3. String carName;
  4. double fuelConsumption;
  5.  
  6. // Constructor
  7. public FuelConsumption(String name, String carName) {
  8. this.name = name;
  9. this.carName = carName;
  10. }
  11.  
  12. // Return Methods
  13. public String returnName() {
  14. return name;
  15. }
  16.  
  17. public String returnCarName() {
  18. return carName;
  19. }
  20.  
  21.  
  22. }

همانطور که در کد فوق ملاحظه می شود یک Comment با عبارت Return Methods در برنامه قرار داده و سپس سه متد از جنس return تعریف کرده ایم. متد اول که reurnName به معنی"مقدار نام را بازگردان" نام دارد قرار است مقدار Field قرار گرفته در کلاس تحت عنوان name را بازگرداند. متد دوم که returnCarName به معنی "مقدار متغیر نام خودرو را بازگردان" نام دارد قرار است مقدار Field قرار گرفته در این کلاس به نام carName را بازگرداند. اکنون کار را در این مرحله برای این کلاس متوقف کرده و اقدام به ایجاد کلاسی جدید تحت عنوان ActionClass به معنی "کلاس عملیاتی" می کنیم. از آنجا که این کلاس قرار است به منزله نقطه شروع برنامه باشد می بایست در حین ساخت آن گزینه public static void main را برای آن تیک بزنیم. پس از ایجاد این کلاس اقدام به ساخت یک شیئ از روی کلاس FuelConsumtion کرده و نام این شیئ را objectOne به معنی "شیئ شماره یک" می گذاریم. در این مرحله کد ما می بایست به صورت زیر باشد:

920629-j43-IMAGE1.jpg

در واقع برای ساخت شیئ objectOne که در تصویر فوق مشاهده می شود، پس از نوشتن کلید واژه new و نوشتن حرف F که حرف اول کلاس FuelConsumption می باشد، اکلیپس به شکل زیر پنجره پیشنهادات را برای ما باز می کند:

920629-j43-IMAGE2.jpg

که با کلیک کردن روی اولین گزینه، اکلیپس به طور خودکار نام پارامترهایی که برای این کلاس در نظر گرفته شده اند را نیز داخل پرانتزها وارد می کند اما این در حالی است که همانطور که در تصویر قبل ملاحظه می شود اکلیپس دور نام پارامتر ها نقطه چین قرار داده و در کنار نام فایل ActionClass.java نیز یک علامت ستاره قرمز رنگ دیده می شود. به طور خلاصه این نقطه چین ها و ستاره قرمز رنگ حاکی از آن هستند که مقدار اختصاص داده شده به پارامترهای داخل پرانتز به درستی وارد نشده اند. در حقیقت در متد Constructor ما دو پارامتر از جنس کلاس String در نظر گرفته و همانطور که قبلا توضیح داده شده است، Value های اختصاص داده شده با String ها می بایست داخل دو علامت “ “ قرار گیرند. حال با دانستن این نکته، به محض اینکه پارامترهای شیئ ساخته شده را داخل علامت “ “ قرار دهیم و برنامه خود را Save کنیم خواهیم دید که ستاره قرمز رنگ و نقطه چین ها از بین خواهند رفت:

920629-j43-IMAGE3.jpg

از آنجا که این دو مقدار اختصاص یافته به عنوان پارامتر دارای نامی گویا نیستند، اسامی آن ها را تغییر داده و نامی دلخواه برای آن ها در نظر می گیریم(به طور مثال به جای name از واژه Behzad و به جای carName از واژه 206 استفاده می کنیم). اکنون کد ما می بایست به صورت زیر باشد:

  1. public class ActionClass {
  2.  
  3. public static void main(String[] args) {
  4. FuelConsumption objectOne = new FuelConsumption("Behzad", "206");
  5. }
  6. }

در حقیقت با این کار مقدار Behzad و 206 برای پارامترهای به ترتیب name و carName موجود در Constructor در نظر گرفته می شوند و از آنجا که پارامترهای موجود در Constructor برابر با Field های به ترتیب name و carName قرار داده شده اند، پس مقادیر Behzad و 206 به Field های مرتبط ارسال می شوند. حال ممکن است که این سوال برای مخاطبین پیش آید که چه طور می توان مقادیر این پارامترها را به صورت دینامیک وارد برنامه کرد که پاسخ به این سوال بسیار ساده است: به کار گیری کلاس Scanner . برای این منظور کلاس ActionClass را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class ActionClass {
  4.  
  5. public static void main(String[] args) {
  6. Scanner keyboardInput = new Scanner(System.in);
  7. String userName = keyboardInput.next();
  8. String userCarName = keyboardInput.next();
  9. FuelConsumption objectOne = new FuelConsumption(userName, userCarName);
  10. }
  11. }

همانطور که در کد فوق ملاحظه می شود یک شیئ از روی کلاس Scanner تحت عنوان keyboardInput به معنی "ورودی کیبورد" ساخته ایم(برای آشنایی بیشتر با کلاس Scanner به آموزش های یازدهم، دوازدهم و سیزدهم مراجعه نمایید). سپس دو Instance یا نمونه از روی کلاس String تحت عناوین userName و userCarName به معانی به ترتیب "نام کاربر" و "نام خودروی کاربر" تعریف کرده ایم. حال به جای آنکه مقادر پارامترهای شیئ ساخته شده از روی کلاس FuelConsomption را به صورت دستی وارد کنیم، صرفا نیاز است تا نام این دو شیئ ساخته شده از روی کلاس String را جای پارامترها قرار دهیم و همانطور که مشاهده می شود داخل پرانتز به جای عبارت Behzad نام userName و به جای عبارت 206 نام userCarName قرار گرفته است. اکنون ما نیاز داریم تا با کاربر خود تعامل داشته باشیم و یکسری اطلاعات به وی داده تا بر آن اساس کاربر داده های خود را وارد برنامه کند. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class ActionClass {
  4.  
  5. public static void main(String[] args) {
  6. Scanner keyboardInput = new Scanner(System.in);
  7. System.out.print("Please enter your name: ");
  8. String userName = keyboardInput.next();
  9. System.out.print("Please enter your Car type: ");
  10. String userCarName = keyboardInput.next();
  11. FuelConsumption objectOne = new FuelConsumption(userName, userCarName);
  12. }
  13. }

به طور خلاصه با قرار دادن دستور System.out.print("Please enter your name: "); روی صفحه نمایش عبارت Please enter your name: به معنی "لطفا نام خود را وارد نمایید:" نمایش داده خواهد شد. سپس دستور String userName = keyboardInput.next(); را قرار داده تا پس از به نمایش آمدن عبارت فوق هر آنچه کاربر به عنوان نام خود تایپ کرد مقابل عبارت Please enter your name: قرار گیرد(در حقیقت از آنجا که از متد print استفاده کرده ایم نشانگر موس برخلاف دستور println به خط بعد انتقال نخواهد یافت). به همین منوال عبارت Please enter your car type را نیز روی صفحه نمایش نشان خواهیم داد و دستور String userCarName = keyboardInput.next(); را پس از آن قرار می دهیم. اکنون یک بار برنامه را اجرا می کنیم:

920629-j43-IMAGE4.jpg

همانطور که ملاحظه می شود در اجرای فوق بنده اول نام خود را وارد کرده سپس نام یک خودرو که در اینجا هامر است را مد نظر قرار داده ام(به محض انجام این کار، این دو نام به عنوان پارامترهای Constructor و بالتبع مقادیر Field های کلاس قبلی مد نظر قرار داده خواهند شد). پس از آنکه ما نام خودروی خود را وارد کنیم و دکمه Enter را فشار دهیم، برنامه دستور دیگری را اجرا نخواهد کرد چرا که دستور دیگری برای برنامه تعریف نکرده ایم. اکنون که توانستیم با موفقیت مقادیر پارامترهای ورودی برنامه را مشخص کنیم، حال نوبت به گرفتن اطلاعات تکمیلی از کاربر پیرامون مسافت طی کرده با خودرو و همچنین مقدار بنزین موجود در باک خودروی وی می رسد. برای این کار کد برنامه را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class ActionClass {
  4.  
  5. public static void main(String[] args) {
  6. Scanner keyboardInput = new Scanner(System.in);
  7. System.out.print("Please enter your name: ");
  8. String userName = keyboardInput.next();
  9.  
  10. System.out.print("Please enter your Car type: ");
  11. String userCarName = keyboardInput.next();
  12.  
  13. FuelConsumption objectOne = new FuelConsumption(userName, userCarName);
  14.  
  15. // Code related to distance and fuel amount
  16. System.out.print("How many kilometers did you go \nwith your car: ");
  17. double distance = keyboardInput.nextDouble();
  18.  
  19. System.out.print("How much petrol did your car have? ");
  20. double petrolUsed = keyboardInput.nextDouble();
  21. }
  22. }

در واقع یک Comment حاوی عبارت Code related to distance and fuel amount به معنی "کد مرتبط با مسافت و مقدار سوخت" قرار می دهیم تا در حین بازبینی کد خود دچار سردرگمی نشویم سپس قصد داریم تا عبارت How many kilometers did you go with your car? به معنی "شما چند کیلومتر با خودروی خود رفتید؟" را روی صفحه مانیتور نمایش دهیم. سپس یک متغیر از جنس double تحت عنوان distance به معنی "مسافت" ایجاد کرده و قصد داریم تا مقدار آن را به صورت دینامیک وارد برنامه کنیم از این رو پس از علامت مساوی نام شیئ ساخته شده از روی کلاس Scanner را نوشته و سپس متد nextDouble را فرا می خوانیم که وظیفه آن گرفتن مقادیر اعشاری از طریق کیبورد است(لازم به ذکر است که اگر کاربر یک عدد صحیح وارد برنامه کند مثلا 90 کیلومتر، برنامه به صورت خودکار آن را به یک عدد اعشاری تبدیل کرده و عدد 90.0 را وارد برنامه خواهد کرد). به همین منوال عبارت How much petrol did your car have? به معنی "خودروی شما چقدر بنزین داشت؟" را روی صفحه مانیتور نمایش داده و سپس متغیری دیگری از جنس double تحت عنوان petrolUsed به معنی "مقدار بنزین مصرف شده" تعریف کرده و مقدار اولیه آن را مساوی با نام شیئ ساخته شده از روی کلاس Scanner قرار داده و سپس متد nextDouble را فرا می خوانیم که وظیفه آن گرفتن مقادیر اعشاری از طریق کیبورد است. اکنون یک بار دیگر برنامه خود را اجرا می کنیم:

920629-j43-IMAGE5.jpg

همانطور که ملاحظه می شود برنامه به درستی کار کرده و اطلاعات به درستی وارد برنامه شدند(همانطور که در تصویر فوق ملاحظه می شود سوال سوم که How many kilometers did you go with your car? است از واژه with به بعد به خط بعد انتقال پیدا کرده است که این کار توسط دستور \ به علاوه حرف n صورت گرفته است که هدف از اینکار صرفا خوانایی بیشتر و بهتر برنامه بوده است). اکنون زمان آن فرا رسیده است تا فرمولی برای به دست آوردن مصرف سوخت بنویسیم:

920629-j43-IMAGE6.jpg

همانطور که در تصویر فوق ملاحظه می شود بنده فرض کرده ام که با هشت لیتر بنزین می توانیم مسافت 115 کیلومتر را طی کنم. حال می خواهیم ببینم که مسافت 100 کیلومتر با چه مقدار بنزین امکان پذیر است. برای این کار عدد 100 را در عدد 8 ضرب کرده و بر عدد 115 تقسیم می کنیم که با اینکار مقدار مجهول ایکس را به دست خواهیم آورد. پس برای اینکه بتوانیم مصرف سوخت را برای برنامه خود به دست آوریم نیاز است تا عدد صد را در مقدار متغیر petrolUsed ضرب کرده و حاصل ضرب این دو عدد را بر مقدار متغیر distance تقسیم کنیم. برای اینکار کد خود را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class ActionClass {
  4.  
  5. public static void main(String[] args) {
  6. Scanner keyboardInput = new Scanner(System.in);
  7. System.out.print("Please enter your name: ");
  8. String userName = keyboardInput.next();
  9.  
  10. System.out.print("Please enter your Car type: ");
  11. String userCarName = keyboardInput.next();
  12.  
  13. FuelConsumption objectOne = new FuelConsumption(userName, userCarName);
  14.  
  15. // Code related to distance and fuel amount
  16. System.out.print("How many kilometers did you go \nwith your car: ");
  17. double distance = keyboardInput.nextDouble();
  18.  
  19. System.out.print("How much petrol did your car have? ");
  20. double petrolUsed = keyboardInput.nextDouble();
  21.  
  22. double result = 100 * petrolUsed / distance;
  23. System.out.println(result);
  24. }
  25. }

همانطور که ملاحظه می شود در دو خط آخر کد، متغیر result به معنی "نتیجه" تعریف شده و فرمول محاسبه مصرف در هر صد کیلومتر برای آن در نظر گرفته شده است سپس مقدار این متغیر در دستور System.out.println قرار گرفته است. حال مجدد برنامه خود را اجرا می کنیم:

920629-j43-IMAGE7.jpg

همانطور که ملاحظه می شود پس از طی مسافتی معادل با 145.5 کیلومتر و مصرف 12 لیتر بنزین برنامه مقدار 8.24 را در هر صد کیلومتر محاسبه کرده است (در واقع خودروی 206 مصرفی معادل با 7 لیتر در هر صد کیلومتر دارد. شاید علت افزایش مصرف سوخت استفاده از کولر باشد!). همانطور که در اجرای فوق مشاهده می شود برنامه یک عدد بسیار دقیق از مقدار مصرف سوخت ما در هر صد کیلومتر ارائه می دهد که شاید برای خیلی از کاربران عددی به این دقت خیلی مهم نباشد و صرفا بخواهند بدانند که مثلا مصرف خودروی ایشان معادل با 8 لیتر در هر صد کیلومتر بوده است. برای این کار می توان از دستور Math.round استفاده کرد به این صورت که مقدار اختصاص داده شده به این دستور رند خواهد شد. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

  1. double result = 100 * petrolUsed / distance;
  2. System.out.println(Math.round(result));

به طور خلاصه با قرار دادن کلاس Math و ضمیمه کردن متد round به آن و قرار دادن متغیری که می خواهیم مقدار آن رند شود(منظور متغیر result است) در داخل پرانتز مقابل متد round می توانیم به نتیجه دلخواه برسیم. اکنون برنامه را با همان اطلاعات ورودی در اجرای فوق مجدد اجرا می کنیم:

920629-j43-IMAGE8.jpg

می بینیم که خروجی برنامه کاملاً رند شده است و برنامه به ما می گوید که پس از طی 145.5 کیلومتر مسافت و مصرف 12 لیتر بنزین، ما در هر صد کیلومتر فقط هشت لیتر بنزین مصرف کرده ایم. اکنون برای تکمیل برنامه ما می توانیم به جای فقط نمایش دادن مقدار متغیر result ، به برنامه خود دستور دهیم که مثلا عبارت Dear Behzad, your 206 car used 8 liters petrol per 100 kilometers. به معنی "بهزاد جان، خودروی 206 شما در هر صد کیلومتر 8 لیتر بنزین مصرف می کند." را روی صفحه نمایش نشان دهد. برای این کار به سادگی می توانیم نام متغیرهای مرتبط با نام، نام خودرو و نتیجه را در دستور System.out.println قرار دهیم و به نتیجه دلخواه برسیم اما از آنجا که در کلاس اول خود یکسری متد بازگشتی تعریف کردیم حال قصد داریم تا برای درک بهتر مفهوم return از آن متد ها در خروجی برنامه خود استفاده کنیم. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class ActionClass {
  4.  
  5. public static void main(String[] args) {
  6. Scanner keyboardInput = new Scanner(System.in);
  7. System.out.print("Please enter your name: ");
  8. String userName = keyboardInput.next();
  9.  
  10. System.out.print("Please enter your Car type: ");
  11. String userCarName = keyboardInput.next();
  12.  
  13. FuelConsumption objectOne = new FuelConsumption(userName, userCarName);
  14.  
  15. // Code related to distance and fuel amount
  16. System.out.print("How many kilometers did you go \nwith your car: ");
  17. double distance = keyboardInput.nextDouble();
  18.  
  19. System.out.print("How much petrol did your car have? ");
  20. double petrolUsed = keyboardInput.nextDouble();
  21.  
  22. double result = 100 * petrolUsed / distance;
  23. System.out.println();
  24.  
  25. System.out.println("Dear " + objectOne.returnName() + ", your "
  26. + objectOne.returnCarName() + " car \nconsumes "
  27. + Math.round(result) + " liters petrol in 100 kilometers.");
  28. }
  29. }

در واقع تنهای تغییری که در کد فوق صورت گرفته است دستور هایی است که داخل System.out.println قرار گرفته است. در ابتدا عبارت Dear به معنی "عزیز" را داخل دو علامت “ “ قرار داده و سپس یک علامت + می گذاریم. سپس شیئی که از روی کلاس FuelConsumption تحت عنوان objectOne ساخته ایم را نوشته و یک نقطه پس از آن قرار می دهیم. در واقع پس از قرار دادن نقطه به کلیه متدهای کلاسی که این شئی از روی آن ساخته شده است دسترسی خواهیم داشت. سپس متدی که قرار بود مقدار Field مرتبط با نام را بازگرداند را می نویسیم. به عبارت دیگر objectOne.returnName() سپس یک علامت به علاوه قرار داده و عبارت , your به معنی "مال شما" را می نویسیم. از آنجا که می خواهیم بگویم مثلا ماشین پژو شما، پس نیاز به نام ماشین داریم. برای این منظور مجدد نام شیئ ساخته شده از روی کلاس FuelConsumption را نوشته و پس از قرار دادن یک نقطه نام متدی را می نویسیم که قرار بود مقدار Field مرتبط با نام خودرو را بازگرداند. به عبارت دیگر نام متد returnCarName() را می نویسیم. سپس یک علامت به علاوه قرار داده و عبارت car consumes به معنی "ماشین استفاده می کند" را می نویسیم(لازم به ذکر است از آنجا که نوشته ما طولانی خواهد شد، برای خوانایی بیشتر می توان از علامت \ به علاوه حرف n در هر جایی از دستور استفاده کنیم که می خواهیم از آن نقطه به بعد به خط بعد منتقل شود). سپس نام متغیر result که قرار بود نتیجه نهایی را اعلام کند می نویسیم. در این کد برای آنکه عدد متغیر result رند شود از کلاسMath و متد round() استفاده می کنیم و نام متغیر result را داخل پرانتز متد round() می نویسیم. آخرین جمله ای که در دستور ما قرار می گیرد عبارت liters petrol in 100 kilometers به معنی "... لیتر بنزین در هر صد کیلومتر" می باشد. اکنون برنامه تکمیل شده و می توانیم برنامه را اجرا کنیم:

920629-j43-IMAGE9.jpg

همانطور که در تصویر فوق ملاحظه می شود برنامه به درستی کار کرده و آخرین دستوری که اضافه کردیم عبارت Dear Behzad, your 206 car consumes 7 liters petrol in 100 kilometers به معنی "بهزاد عزیز، ماشین 206 شما در هر 100 کیلومتر مقدار 7 لیتر بنزین مصرف می کند" را به ما نشان می دهد. جهت یادآوری عرض می کنیم که در این دستور آخر مقادیر Behzad و 206 از طریق متدهای بازگشتی کلاس اول فرا خوانده شده اند.

چهارشنبه 2 بهمن 1392  12:09 PM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۴۴: آشنایی با انواع Import و بررسی کلاس Math قسمت اول


در این آموزش و آموزش بعد قصد داریم تا یکی از پرکاربردترین کلاس های ساخته شده در API زبان برنامه نویسی جاوا را مورد بررسی قرار دهیم. به طور خلاصه می توان گفت که اگر بخواهیم از اعمال ریاضیاتی در طراحی برنامه های خود بهره مند شویم، می بایست از کلاس Math و متدهای مختلف مرتبط با این کلاس استفاده کنیم(توجه داشته باشید که حرف اول این کلاس با حرف بزرگ نوشته می شود).

در ابتدا پروژه ای تحت عنوان 44th Session ایجاد کرده و کلاسی تحت عنوان MathClass به معنی "کلاس ریاضیات" در آن ایجاد می کنیم و پیش از کلیک کردن بر روی دکمه Finish گزینه public static void main را تیک دار می کنیم.

اکنون برای آنکه بتوانیم متدهای مختلف کلاس Math را مورد بررسی قرار داده و خروجی این متدها را مشاهده کنیم، نیاز است تا دستور System.out.println(); را در کد خود اضافه کنیم. در این مرحله از کار، کد برنامه می بایست به صورت زیر باشد:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println();
  4.  
  5. }
  6. }

حال چنانچه هر چیزی را داخل متد println قرار دهیم در پنجره Console به نمایش در خواهد آمد. در این آموزش پیش از آشنایی با کلاس Math به دو رویکرد در Import کردن کلاس های مختلف در پروژه خود خواهیم پرداخت سپس با متدهای abs و ceil و floor آشنا خواهیم شد. به طور خلاصه می توان گفت که کلیه کلاس های API زبان جاوا به دو صورت Implicit و Explicit به ترتیب به معانی "نا آشکار" و "آشکار" به برنامه ما Import می شوند. به طور مثال کلاسی همچون کلاس Scanner به صورت Explicit یا واضح و آشکار به برنامه Import می شود. به عبارت دیگر پس از به کار گیری از این کلاس در برنامه خود، در اولین خط از کد برنامه دستور import java.util.Scanner; را خواهیم دید. از سوی دیگر یکسری از کلاس ها مثل کلاس String و یا کلاس Math و بسیاری از دیگر کلاس های زبان جاوا هستند که به صورت Implicit یا نا آشکار به برنامه Import می شوند. به طور مثال زمانیکه ما در برنامه خود از کلاس String استفاده می کنیم، مشاهده می شود که هیچ دستور Import یی در برنامه مشاهده نمی شود و این مسئله به این خاطر است که این کلاس به صورت ضمنی یا نا آشکار در هر پروژه ای که در اکلیپس بسازیم Import خواهد شد. کلاس Math هم به همین صورت است. به عبارت دیگر برای استفاده از این کلاس نیازی به Import کردن آشکارا یا Explicit این کلاس نداریم. اولین متدی که از کلاس Math می خواهیم مورد بررسی قرار دهیم، متد abs است که مخفف واژه absolute به معنی "مطلق" است. کاری که این متد انجام می دهد این است که هر عددی که داخل آن قرار گیرد خواه مثبت و خواه منفی، آن عدد را به یک عدد مثبت تبدیل می سازد. برای روشن شدن موضوع، کد فوق را به شکل زیر تکمیل می کنیم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.abs(-100));
  4. }
  5. }

همانطور که مشاهده می شود، به منظور استفاده از کلاس Math نام این کلاس را نوشته سپس یک نقطه قرار داده و پس از آن نام متدی که می خواهیم مورد استفاده قرار دهیم را می نویسیم. در واقع پس از نوشتن نام کلاس Math و قرار دادن یک نقطه، اکلیپس به صورت خودکار کلیه متدهای مرتبط با این کلاس را برای ما خواهد آورد:

920702-j44-IMAGE1.jpg

چنانچه اکلیپس این کار را به صورت خودکار انجام نداد، به سادگی با فشردن هم زمان کلید های Ctrl و Space می توان به پنجره فوق دست پیدا کرد. اکنون از میان کلیه متدها، متد abs را می خواهیم مورد استفاده قرار دهیم. برای این منظور یا می توان حروف abs را به صورت دستی پس از نقطه نوشت و یا همانطور که در پنجره فوق مشاهده می شود می توان روی یکی از گزینه های مرتبط با abs کلیک کرد(از آنجا که می خواهیم در این مثال یک عدد صحیح را مورد بررسی قرار دهیم، از این رو روی گزینه abs(int a) : int – Math کلیک می نماییم). سپس در پرانتزهای داخل این متد یک عدد مثل منفی صد وارد می کنیم. اکنون پس از اجرای برنامه، خروجی زیر مشاهده خواهد شد:

920702-j44-IMAGE2.jpg

همانطور که ملاحظه می شود با استفاده از این متد، عدد منفی صد به عدد 100 تبدیل شده است. متد دیگر که از کلاس Math می خواهیم مورد بررسی قرار دهیم، متد ceil() است. در واقع کلید واژه ceil مخفف واژه ceiling به معنی "سقف اتاق" است. داده ای که این متد می گیرد از نوع عدد اعشاری است و کاری که این متد انجام می دهد این است اعداد اعشاری را رو به بالا رند می سازد. مثلا اگر عدد 12.3 را داخل این متد قرار دهیم، پس از اجرای برنامه این عدد به عدد 13 تغییر پیدا خواهد کرد:

920702-j44-IMAGE3.jpg

برای روشن شدن مطلب کد فوق را به شکل زیر تکمیل می کنیم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.ceil(12.3));
  4. }
  5. }

همانطور که در کد فوق ملاحظه می شود، پس از کلاس Math متد ceil قرار گرفته و داخل پرانتزهای این متد عدد 12.3 را نوشته ایم. حال برنامه را اجرا می کنیم:

920702-j44-IMAGE4.jpg

همانطور که در اجرای فوق ملاحظه می شود، عدد 12.3 به عدد 13 تغییر یافته است. متد متضاد ceil() متدی است تحت عنوان floor() به معنی "کف اتاق" است که کار این متد این است که اعداد اعشاری را رو به پایین رند می کند:

920702-j44-IMAGE5.jpg

برای روشن شدن مطلب کد پیشین را به صورت زیر بازنویسی می کنیم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.floor(12.3));
  4. }
  5. }

حال کد فوق را اجرا می کنیم:

920702-j44-IMAGE6.jpg

همانطور که مشاهده می شود متد floor عدد 12.3 را رو با پایین رند کرده و آن را به عدد 12 کاهش داده است.

چهارشنبه 2 بهمن 1392  12:11 PM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۴۵: بررسی کلاس Math قسمت دوم


در ادامه مبحث متدهای کلاس Math در این آموزش از پروژه ای که در آموزش چهل و چهارم ایجاد کردیم استفاده خواهیم کرد و متد های max و min و pow و sqrt و round را مورد بررسی قرار خواهیم داد.

اولین متدی که می خواهیم مورد بررسی قرار دهیم، متد max() است که مخفف واژه maximum به معنی "حداکثر" می باشد. در واقع این متد برخلاف متدهای پیش دو پارامتر را در خود جای می دهد که با یک کاما از یکدیگر جدا می شوند. وظیفه این متد آن است که از بین این دو عدد، عددی که بزرگ تر را گرفته و نمایش دهد. برای روشن شدن این مسئله کد فوق را به شکل زیر تغییر می دهیم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.max(12, 22));
  4. }
  5. }

همانطور که ملاحظه می شود، در کد فوق پس از استفاده از متد max دو پارامتر 12 و 22 داخل این متد قرار داده ایم که با استفاده از یک کاما از یکدیگر جدا شده اند. حال انتظار می رود پس از اجرای برنامه خود، عدد بزرگ تر (عدد 22) روی صفحه مانیتور نمایش داده شود:

920704-j45-IMAGE1.jpg

همانطور که انتظار می رفت عدد 22 نمایش داده شد. حال ببینیم اگر یک عدد اعشاری داشته باشیم و یک عدد صحیح چه اتفاقی خواهد افتاد. برای این منظور کد فوق را به صورت زیر بازنویسی می کنیم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.max(12.1, 22));
  4. }
  5. }

برای روشن شده مسئله برنامه را یک بار اجرا می کنیم:

920704-j45-IMAGE2.jpg

همانطور که انتظار می رفت باز هم عدد بزرگ تر نمایش داده شده اما چیز عجیبی که در مورد خروجی برنامه وجود دارد این است که عدد 22 که یک عدد صحیح بود به یک عدد اعشاری تبدیل شده است و عدد 22.0 در پنجره Console نمایش داده شده است. در پاسخ به این مسئله بایستی گفت که پارامترهای ورودی این متد می تواند هم از جنس متغیر int باشد و هم از جنس متغیر double ولی از آنجا که یکی از متغیرها در مثال فوق از جنس عدد صحیح است و عدد دیگر از جنس عدد اعشاری، علیرغم اینکه عدد 22 یک عدد صحیح است ولی به یک عدد اعشاری با همان مقدار قبلی تبدیل می شود. متدی که در مقابل متد max قرار دارد متد min است که مخفف واژه minimum به معنی "حداقل" است. وظیفه ای که این متد بر عهده دارد این است که از میان دو پارامتر ورودی، پارامتر کوچک تر را برگزیند. برای روشن شدن این مسئله، کد فوق را به شکل زیر بازنویسی می کنیم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.min(12.1, 22));
  4. }
  5. }

پس از اجرای کد فوق، می بایست عدد کوچکتر که در این مثال عدد 12.1 است در پنجره Console نمایش داده شود:

920704-j45-IMAGE3.jpg

پس از اجرای برنامه خواهیم دید که عدد 12.1 نمایش داده می شود. یکی از معانی واژه power در زبان فارسی "توان" است. به طور مثال اگر بخواهیم بگوییم دو به توان سه بایستی در زبان انگلیسی گفت Two to the power of three . اکنون با دانستن این نکته می توانیم کاربرد متد pow() را حدس بزنیم. در حقیقت این متد می تواند دو پارامتر را در خود جای دهد به طوریکه پارامتر اول عددی است که می خواهیم به توان برسانیم و پارامتر دوم توان است(لازم به ذکر است که این دو پارامتر از یکدیگر بوسیله یک کاما جدا می شوند). اکنون با دانستن این نکته می توانیم کد فوق را به صورت زیر بازنویسی نماییم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.pow(2, 3));
  4. }
  5. }

چنانچه بخواهیم کد فوق را تفسیر نماییم، بایستی بگوییم که پس از نوشتن نام کلاس Math یک نقطه قرار داده سپس مد توان تحت عنوان pow را نوشته و دو پارامتر ورودی را به صورت فوق داخل پرانتزها می نویسیم. در حقیقت عدد 2 به عنوان عددی است که می خواهد به توان عدد 3 برسد، به عبارت دیگر عدد 2 می بایست در عدد 2 ضرب شده و سپس حاصلضرب آن در عدد 2 مجدد ضرب گردد. اکنون برنامه را اجرا می کنیم:

920704-j45-IMAGE4.jpg

همانطور که مشاهده می شود نتیجه 8.0 نمایش داده شده است(به عبارت دیگر حاصلضرب 2 در 2 می شود 4 و حاصلضرب 4 در 2 می شود 8). متدی دیگری که از کلاس Math می توان مورد استفاده قرار داد متدی است که جذر اعداد را به دست می آورد. در زبان فارسی واژه Square دارای معانی متعدی همچون "مربع، میدان" و غیره است اما در ریاضیات این واژه به معنی "مجذور" است. در زبان برنامه نویسی جاوا متدی که مجذور اعداد را به دست می آورد از مخفف این واژه و واژه Root به معنی "ریشه" بوده و به صورت sqrt نوشته می شود. به عبارت دیگر عبارت Square Root به معنی "جذر" در ریاضیات می باشد. اکنون پس از آشنایی با این متد می توانیم کد خود را به شکل زیر بازنویسی کنیم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.sqrt(9));
  4. }
  5. }

در کد فوق نام متد sqrt نوشته شده و سپس داخل پرانتز مرتبط با آن عدد 9 را نوشته ایم. در حقیقت علت انتخاب عدد 9 در این مثال این است که این عدد دارای یک مجذور رند می باشد. اکنون پس از اجرای برنامه خواهیم دید که جذر عدد 9 که معادل به 3 می باشد نمایش داده خواهد شد:

920704-j45-IMAGE5.jpg

متد دیگر که در برنامه نویسی جاوا و اندروید بسیار کاربردی است، متد round() است. به طور خلاصه هر عددی که داخل پرانتز این متد قرار گیرد به عددی رند تبدیل خواهد شد اما نکته ای که در اینجا می بایست مد نظر قرار داده شود این است که اگر عددی همچون 21.3 وارد این متد شود، این عدد رو به پایین رند خواهد شد و عدد 21 به دست خواهد آمد. به طور کلی اگر خرده اعشاری این عدد کوچکتر از 5 باشد این عدد رو به پایین رند خواهد شد و اگر خرده اعشاری این عدد برابر با 5 و یا بزرگتر باشد(مثلا عدد 21.6 ) این عدد رو به بالا رند خواهد شد و عدد 22 به دست خواهد آمد. برای روشن شدن مطلب کد خود را به شکل زیر بازنویسی می کنیم:

  1. public class MathClass {
  2. public static void main(String[] args) {
  3. System.out.println(Math.round(12.3));
  4. }
  5. }

همانطور که ملاحظه می شود عدد 12.3 برای این متد در نظر گرفته شده است و بر اساس توضیحات پیشین انتظار می رود که خروجی برنامه عدد 12 باشد. برای حصول اطمینان از این خروجی برنامه را یک بار اجرا می کنیم:

920704-j45-IMAGE6.jpg

می بینیم که این عدد اعشاری رو به پایین رند شده و خروجی برنامه معادل با عدد 12 است. حال اگر عدد داخل این متد را به عدد 12.6 تغییر دهیم از آنجا که خرده اعشاری این عدد بزرگتر از 5 است، از این رو این عدد رو به بالا رند خواهد شد و خروجی برنامه عدد 13 را نشان خواهد داد. حال مجدد برنامه را به اعمال این تغییر اجرا می کنیم:

920704-j45-IMAGE7.jpg

همانطور که گفته شد برنامه عدد 13 را نمایش می دهد.

چهارشنبه 2 بهمن 1392  12:12 PM
تشکرات از این پست
hosseinb68
hosseinb68
کاربر طلایی1
تاریخ عضویت : بهمن 1389 
تعداد پست ها : 1269
محل سکونت : بوشهر

آموزش برنامه نویسی جاوا - قسمت ۴۶: بررسی دستور enum در قالب پروژه نتایج تیم های پیروزی و استقلال‎


همانطور که پیش از این توضیح داده شد، متغیری از جنس boolean زمانی مورد استفاده قرار می گیرد که دو حالت بیشتر پیش روی ما وجود نداشته باشد. حال اگر ما در شرایطی قرار بگیریم که بیش از دو حالت پیش روی ما باشد مسلماً از این نوع متغیر نخواهیم توانست استفاده کنیم و از همین رو است که طراحان زبان برنامه نویسی جاوا ساختاری تحت عنوان Enumeration را در این زبان شیئ گرا گنجانده اند. معادل فارسی واژه Enumeration برابر است با "شمارش" و این در حالی است که در زبان برنامه نویسی جاوا این واژه به صورت خلاصه درآمده و به شکل enum نوشته می شود. چنانچه بخواهیم موارد استفاده enum را برشمریم به لیست بلندی از کاربردهای این دستور برخواهیم خورد که در ادامه به برخی از مثال ها اشاره خواهیم کرد.

یک چراغ راهنمایی دارای سه حالت سبز، قرمز و زرد است. روزهای هفته شنبه، یکشنبه، دوشنبه، سه شنبه، چهارشنبه، پنج شنبه و جمعه را شامل می شود. یک کشور می تواند توسعه یافته، در حال توسعه و عقب افتاده باشد! اینها مثال هایی هستند که اگر بخواهیم برنامه ای در رابطه با آنها بنویسیم ناگزیر می بایست از enum ها استفاده کنیم.

در ابتدا طبق روال گذشته یک سناریو تعریف کرده و بر اساس آن برنامه ای می نویسیم.

یک مسابقه فوتبال می تواند سه نتیجه متفاوت داشته باشد: حالت اول اینکه تیم الف برنده و تیم ب بازنده است، حالت دوم اینکه تیم ب برنده و تیم الف بازنده است، حالت سوم اینکه نتیجه مسابقه مساوی می شود (البته در برخی مواقع حالت چهارمی هم وجود دارد مبنی بر اینکه بازیکنان شروع به زد و خورد کرده و داور مسابقه را لغو می کند.)
برای شروع کار پروژه ای تحت عنوان 46th Session ایجاد کرده و کلاسی تحت عنوان FootballMatch به معنی "بازی فوتبال" در آن ایجاد می کنیم.

حال می بایست کد ما به شکل زیر باشد:

  1. public class FootballMatch {
  2.  
  3. public static void main(String[] args) {
  4. }
  5. }

از آنجا که نیاز داریم تا این امکان را به کاربر بدهیم تا بتواند نتیجه بازی را وارد برنامه کند، به استفاده از کلاس Scanner پرداخته و کد خود را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class FootballMatch {
  4.  
  5. public static void main(String[] args) {
  6. Scanner keyboardInput = new Scanner(System.in);
  7. }
  8. }

همانطور که در کد فوق ملاحظه می شود، شیئی تحت عنوان keyboardInput به معنی "ورودی کیبورد" ایجاد کرده ایم(به منظور آشنایی بیشتر با کلاس Scanner به آموزش های یازدهم و دوازدهم مراجعه نمایید). اکنون به صورت زیر اقدام به ساخت enum این برنامه می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class FootballMatch {
  4. enum WhoWins {
  5. Perspolis, Esteghlal, Equal
  6. };
  7. public static void main(String[] args) {
  8. Scanner keyboardInput = new Scanner(System.in);
  9. }
  10. }

همانطور که در کد فوق مشاهده می شود، پیش از کد مربوط به متد main اقدام به نوشتن کد مربوط به enum می کنیم به این صورت که اول کلید واژه enum را نوشته سپس نامی دلخواه برای آن در نظر می گیریم که در این مثال نام WhoWins به معنی "چه کسی برنده می شود" انتخاب شده است. سپس یک علامت { قرار داده و اقدام به نوشتن حالتهای مد نظر خود می کنیم به این صورت که آنها را با یک علامت کاما از یکدیگر جدا می سازیم و در نهایت یک علامت } قرار داده و پس از آن یک ; قرار می دهیم(لازم به ذکر است که به هر تعداد حالت که بخواهیم می توانیم برای enum خود در نظر بگیریم). در این مثال سه حالت پرسپولیس، استقلال و برابر را در نظر گرفته ایم. اکنون نیاز داریم تا از کاربر بخواهیم که نتیجه تیم پرسپولیس را وارد کند. برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class FootballMatch {
  4.  
  5. enum WhoWins {
  6. Perspolis, Esteghlal, Equal
  7. };
  8. public static void main(String[] args) {
  9. Scanner keyboardInput = new Scanner(System.in);
  10. System.out.print("Please enter the score of Perspolis: ");
  11. int perspolisScore = keyboardInput.nextInt();
  12. }
  13. }

همانطور که در کد فوق مشاهده می شود با استفاده از دستور System.out.println جمله ای را به معنی "لطفاً تعداد گل های تیم پرسپولیس را وارد نمایید: " در پنجره Console نمایش خواهیم داد. سپس متغیری از جنس int تحت عنوان perspolisScore به معنی "امتیاز پرسپولیس" ایجاد کرده و مقدار آن را معادل با شیئ ساخته شده از روی کلاس Scanner به علاوه متدی برای گرفتن اعداد صحیح از کیبورد که همان nextInt است قرا می دهیم. حال به صورت زیر همین مراحل را برای تیم استقلال تکرار می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class FootballMatch {
  4. enum WhoWins {
  5. Perspolis, Esteghlal, Equal
  6. };
  7. public static void main(String[] args) {
  8. Scanner keyboardInput = new Scanner(System.in);
  9. System.out.print("Please enter the score of Perspolis: ");
  10. int perspolisScore = keyboardInput.nextInt();
  11. System.out.print("Please enter the score of Estghlal: ");
  12. int esteghlalScore = keyboardInput.nextInt();
  13. }
  14. }
  15.  

به طور خلاصه مجدد با استفاده از دستور System.out.println عبارتی به معنی "لطفاً تعداد گل های تیم استقلال را وارد نمایید: " را روی صفحه مانیتور به نمایش درآورده سپس متغیری از جنس int تحت عنوان esteghlalScore به معنی "امتیاز استقلال" ایجاد کرده و مقدار آن را معادل با شیئ ساخته شده از روی کلاس Scanner به علاوه متدی برای گرفتن اعداد صحیح از کیبورد که همان nextInt است قرا می دهیم. اکنون برنامه را اجرا می کنیم:

920713-j45-IMAGE 1.jpg

همانطور که در تصویر فوق ملاحظه می شود، جمله اول به نمایش درآمده که از طریق کیبورد می توانیم عددی برای آن در نظر بگیریم و به محض وارد کردن عدد اول و فشردن دکمه Enter جمله دوم به نمایش در آمده و خواهیم توانست عددی برای آن در نظر بگیریم. به طور کلی می توان گفت که enum یک نوع Class است که تغییر شکل داده است(اگر توجه کرده باشیم، خواهیم دید که نحوه نامگذاری آن هم بی شباهت به نامگذاری کلاس ها نیست چرا که با حرف بزرگ آن را نامگذاری کرده ایم). حال به منظور مقایسه کردن نتایج هر دو تیم اقدام به استفاده از دستورات شرطی if می کنیم:

  1. import java.util.Scanner;
  2.  
  3. public class FootballMatch {
  4.  
  5. enum WhoWins {
  6. Perspolis, Esteghlal, Equal
  7. };
  8. public static void main(String[] args) {
  9. Scanner keyboardInput = new Scanner(System.in);
  10. System.out.print("Please enter the score of Perspolis: ");
  11. int perspolisScore = keyboardInput.nextInt();
  12. System.out.print("Please enter the score of Estghlal: ");
  13. int esteghlalScore = keyboardInput.nextInt();
  14. if (perspolisScore > esteghlalScore) {
  15. System.out.print(WhoWins.Perspolis);
  16. } else if (esteghlalScore > perspolisScore) {
  17. System.out.print(WhoWins.Esteghlal);
  18. } else {
  19. System.out.print(WhoWins.Equal);
  20. }
  21. }
  22. }

به طور کلی به منظور دسترسی به یکی از داده های enum که در این مثال WhoWins نام دارد، اول WhoWins را نوشته و پس از قرار داده یک نقطه نام یکی از داده های داخل enum را می نویسیم. به طور خلاصه به صورت زیر می توان به یکی از داده های enum دست پیدا کرد:

  1. WhoWins.Perspolis;

در اولین عبارت شرطی قید کرده ایم که اگر امتیاز پرسپولیس از استقلال بالاتر بود دستور System.out.println مقدار WhoWins.Perspolis را نمایش دهد، و اگر امتیاز استقلال از پرسپولیس بالاتر بود دستور System.out.println مقدار WhoWins.Esteghlal را نمایش دهد و در غیر اینصورت دستور System.out.println مقدار WhoWins.Equal را نمایش دهد. اکنون سه بار اقدام به اجرای برنامه می کنیم:

920713-j45-IMAGE 2.jpg

در اجرای اول امتیاز پرسپولیس را 4 در نظر گرفته و امتیاز استقلال را 2 که پس از فشردن دکمه Enter خواهیم دید که عبارات شرطی اقدام به نمایش گزینه ای از مقادیر enum می کنند که مرتبط با پرسپولیس است.

920713-j45-IMAGE 3.jpg

در اجرای دوم امتیاز پرسپولیس را 2 در نظر گرفته و امتیاز استقلال را 4 که پس از فشردن دکمه Enter خواهیم دید که عبارات شرطی اقدام به نمایش گزینه ای از مقادیر enum می کنند که مرتبط با استقلال است.

920713-j45-IMAGE 4.jpg

در اجرای سوم امتیاز پرسپولیس را 0 در نظر گرفته و امتیاز استقلال را 0 که پس از فشردن دکمه Enter خواهیم دید که عبارات شرطی اقدام به نمایش گزینه ای از مقادیر enum می کنند که مرتبط با برابری هر دو تیم است.

چهارشنبه 2 بهمن 1392  12:14 PM
تشکرات از این پست
دسترسی سریع به انجمن ها