نکات گنگی از شی گرایی
سلام
دوستان برای من خیلی از قسمت های کد نویسی که بیشتر مربوط به شی گرایی هست، گنگه. برای مثال:
ما در تعریف آرایه ها داشتیم:
int[] numbers=new int[10];
می دانیم که int یک primitive هست و کلاس نیست ولی این شکل تعرف مشابه تعریف کلاس هست:
Car mycar=new Car();
از طرف دیگه گفتیم String کلاس هست نه primitive ولی وقتی می خواهیم یه رشته تعریف کنیم میگیم:
String str;
که مشابه تعریف primitive هست.ممنون میشم برام توضیح بدید. فقط این نکته رو بگم که من الان به بخش هفتم آموزشها رسیدم. اگر این نکات در جلسات بعد توضیح داده میشه، لطفا بگید کدوم جلسه. ولی فکر می کنم بحث شی گرایی مبحثش کامل شده و الان من باید این نکات رو بدونم ولی نمی دونم. ممنون میشم برام شرح بدید.
دوست عزیز در اصلی همونطور که دوستان و استاد بارها ذکر کردن در اصل بهتر هستش که در اول راه بیشتر کلیشه ای ساختار تعاریف رو یاد بگیرید. اما حالا یه توضیح مختصری دارم در این زمنیه :
تو تعریف یک متغیر از نوع کلاس یا Primitive هیچ فرقی وجود ندارد مانند :
int i;
String str;
Integer f;
میبینید که متغیر i از نوع primitive بوده اما f از نوع کلاس Integer که اصلا با کاربردشون کاری نداریم فقط همین که بدونیم تو تعاریف تفاوتی وجود ندارد نه تنها در زبان جاوا بلکه در تمام زبان های برنامه نویسی که تا کنون دیدیم...
اما حالا چون میدونیم یک آرایه مجموعه ای از عناصر هم نوع است همونطور که دوستمون در بالا گفتند میخواهم یه مثال بزنم :
مثلا تو یه فروشگاه بزرک مثل هایپرمارکت ها میوه ها رو در یک قسمت و مثلا لباس ها رو در قسمت دیگه و دیگر اجناس رو در قسمت های دیگر میگذارند یعنی کاری ندارند که در مرحله اول چه میوه ای هست؟ مهم اینه که میوه هست پس تو یک کلاس میوه میزارند. بعد که وارد اون قسمت میشیم آیا درسته که مثلا سیب و پرتغال قاطی بشه ؟ نه! پس دوباره میایم به کلاس های کوچکتری تقسیم میکنیم کلاس سیب و کلاس پرتغال. همون مفهوم برای آرایه ها وجود داره ما در مرحله اول آرایه ای از نوع Object داریم که اصلا کاری نداره سیب هست یا پرتغال ! مانند :
Object[] objMiveh = new Object[n];
این آرایه همونطور که استاد بارها تو آموزش ها در صورت نیاز استفاده کردن هر نوعی رو میپذیره حالا اون عدد باشه یا رشته همون جریان سیب و پرتغال! حال اگه بخواهیم محدودتر کنیم از یه نوع خاص استفاده میکنیم مانند :
int[] intVal = new int[n];
همونطور که میبینید اینجا آرایه ای تعریف کردیم از اعداد صحیح فقط عدد صحیح میگیرن همون جریان کلاس فقط سیب یا فقط پرتغال هستش!
خب اول هم گفتیم تعریف آرایه ها مانند کلاس ها هست مثلا :
Car myCar = new Car();
اینجا دیگه کاری نداریم ماشین ما از چه نوعی است میتونه پراید یا پژو یا غیره باشه حال اگه بخواهیم کلاسی برای پرایدها فقط ایجاد کنیم مانند :
Pride myPride = new Pride();
اینجا دیگه فقط کلاس ما توش ماشین های پراید هستش. اما حالا مگه ما چند تا کلاس از ماشین های متفاوت نداریم ؟! پس بهتره که یه کلاس از نوع Car میسازیم. مثلا مشخصه هایی رو توش که شباهت دارن رو تعریف میکنیم مانند کشور ساخت مثلا آلمان باشه توی این کلاس تعریف میکنیم. بعد تو کلاس های Benz و BMW دیگه نمیایم بگیم کشور ساخت آلمان اگه بگیم ایرادی نداره اما خوش آیند نیس! بلکه تو کلاس ماشین میگیم بعد کلاس های Benz و BMW رو از اون کلاس ارث بری میکنیم.
امیدوارم تونسته باشم کمکی در فرآیند یادگیری کنم اما شما اگه اینا رو مطالعه و دقت کنین دیگه آموزش های استاد رو کاملا متوجه میشین در بخش شی گرایی OOP. باز جایی نا مفهوم بود در خدمتم.
خیلی ممنونم از لطفتون
این نکته که گفتید:"تو تعریف یک متغیر از نوع کلاس یا Primitive هیچ فرقی وجود ندارد" خیلی مفید بود چون تصور من این بود که متغیر فقط زمانی معنا داره که با primitive ها روبرو هستیم و در مورد کلاس، فقط میشه یک نمونه از اون رو تعریف کرد نه یک متغیر از نوع کلاس.
اما در مورد شکل تعریف آرایه راستش هنوز مقداری مشکل دارم. فکر کنم باید بیشتر روی مطلب و توضیح شما فکر کنم. اگر به نتیجه نرسیدم بازم وقت تون رو میگیرم. سپاس فراوان
نوع داده های اولیه (Primitive) در واقع به عنوان والد نوع های پیشرفته محسوب می شوند.
وقتی شما دو عدد رو می خواهید با هم جمع کنید مثلا از دو نوع متغیر int استفاده می کنید.
مثال: می خواهیم مشخصات یک دانشجو رو داشته باشیم. آیا با نوع های پایه نمیشه برنامه رو نوشت؟
چرا که نه ؟! دانشجو : نام، نام خانوادگی، شماره دانشجویی، شماره ملی ، وضعیت (فعال/غیرفعال) و ... از نوع string و int و ..
- خوب حالا شما می خواهید یک دانشجو را بین تابع های مختلف ارسال و یا از آن دریافت کنید؛ شما باید تمام مشخصات (Property) مربوط به دانشجو را در امضا تابع های خود وارد کنید. ممکن است برنامه نویس شما بعضی از فیلدها رو فراموش کنه. چه برنامه ناخوانا و ناقصی خواهد بود!
- نام و نام خانوادگی دانشجو از هم جدا هستند؛ برای خروجی شما می خواهید این دو قسمت به صورت یک رشته به خروجی ارسال شود : مثلا: علی علیزاده. شما در تمام قسمت های لازم (مثلا 10 جا) تمام name و family را با هم جمع می کنید و به خروجی ارسال می کنید. بعداز مدتی از شما خواسته می شود که خروجی به صورت اول family و بعد خط تیره و name باشد: علیزاده - علی
حالا باید تمام موارد جمع کردن دو رشته را پیدا و تغییرات لازم را اعمال کنید. هدر رفتن زمان! - بدتر از همه به علت در هم بودن کدها (به قول معروف اسپاگتی کد) و شیوه ای که هر برنامه نویس ممکن هست داشته باشه، بعد از مدتی که به کدها سر می زنید باید ساعتی را صرف تجزیه و تحلیل کار خود کنید. بدتر از آن زمانی است که برنامه نویس دیگری کد را نوشته باشد و شما بخواهید اصلاحاتی انجام دهید. نگهداری کدها سخت می شود.
شی گرایی به شما پیشنهاد می کنه که دانشجو رو تبدیل به یک کلاس (نقشه ساختار مورد نظر) کنید با فیلدها و متدهای مربوطه (آن چیزهایی که نیاز دارید و واقعا متعلق به آن می باشد).
در هر قسمت کد ، که نیاز به دانشجو دارید از روی کلاس آن یک شی می سازید. در پارامترهای ارسالی به تابع فقط کافیست که متغیری از نوع دانشجو داشته باشید ویا حتی خروجی تابع. وقتی احتیاج به تغییری در کلاس دانشجو داشته باشید می دانید مستقیما به کجا رجوع کنید. شی گرایی ممکن است کد نویسی را زیاد کند (ساختن کلاس ها) اما خوانایی برنامه شما را افزایش ، کد نویسی را راحتتر و ... می کند.
مثلا در کلاس ArrayList شما متدی (set) دارید که وظیفه اضافه کردن آیتم مورد نظر به لیست را دارد. شما تنها استفاده کننده هستید. چه اتفاقی در این متد می افتد؟ شما نمی دانید و لازم هم نیست که بدانید و ...
عجله نکنید! شما با انجام پروژه های مختلف ، کسب تجربه و مطالعه با این مفاهیم و دیگر مفاهیم بیشتر آشنا خواهید شد .
موفق باشید!
از اینکه وقت میگذارید و پاسخ میدهید بینهایت ممنونم.
Eminent عزیز فکر کنم منظور شما رو در مورد قسمت اول سوالم متوجه شده ام:
ما در تعریف داریم:
int i;
Integer f;
ولی اولی یک متغیر ایجاد می کند و دومی یک نمونه از کلاس.
اما در مورد قسمت دوم سوالم، اجازه بدهید به شکل دیگری مطرح کنم:
اگر داشته باشیم:
int[] numbers=new int[2];
در اینجا numbers یک نمونه از کلاس است یا متغیر؟
شما در مفهوم متغیر دچار اشتباه شده اید:
متغیر محلی در حافظه هست که مقداری را در خودش ذخیره می کند. حتی ثابت ها (constant) که زمان تعریف با final تعریف می شوند متغیرهایی از نوع غیر قابل تغییر هستند. اشیا هم متغیرهای ساختیافته محسوب می شوند نه چیز دیگر.
اما آرایه : کلکسیونی (Collection) با طول ثابت از عناصر هم نوع می باشد، یعنی ظرفی با گنجایش ثابت است که یک نوع خاص را می توانید به آن اختصاص دهید. array یک کلاس محسوب می شود:
- برای اینکه مشخص کنید از این کلاس استفاده می کنید از براکت " [ ] " استفاده می کنید.
- برای اینکه مشخص کنید چه نوعی را می تواند در خود نگهدارد، نوع آن را مشخص می کنید.
- اگر دقت کرده باشید شامل متدهایی مثل clone و length و ... می باشد. انواع اولیه (primitive) بدون متد هستند.
- در collection های جدید، تعریف آنها تقریبا شبیه به تعریف اشیا است.
Car [] myCars=new Car [10];
int[] numbers=new int[2];
ArrayList<Car> myList =new ArrayList<Car>
در نتیجه «متغیرهای» myCars و numbers هر دو شی محسوب می شوند. با یک تفاوت در زمان مقدار دهی:
numbers[1]=4;
myCars[1]=new Car();
نوع car چون کلاس هست باید با new به هر خانه از آرایه اختصاص داده شود. یعنی تا زمانی که شما از new استفاده نکنید شی ای از Car ساخته نشده و حافظه ای به آن تعلق نمی گیرد. در زمان تعریف آرایه از نوع Car ، فقط نوع آرایه و طول آن را مشخص می کنید ولی فضایی از حافظه به آن اختصاص داده نمی شود.
ولی در نوع int به محض new کردن در زمان تعریف آرایه، حافظه به آن تعلق خواهد گرفت (چون نوع primitive می باشد) ، در نتیجه نیازی به استفاده از new برای هر عنصر آرایه نخواهید داشت.
علت، تفاوت در نوع حافظه ای است که به نمونه ای از کلاس و انواع اولیه اختصاص داده می شود.
موفق باشید!
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .