شی گرایی به زبان ساده

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

برنامه نویسی رویه ای ​

زبانهای برنامه نویسی رو میشه به دو دسته برنامه نویسی رویه ای و برنامه نویسی شی گرا دسته بندی کرد. برنامه نویسی رویه ای در واقع میشه همین کدهایی که تا الان (جلسات قبلی) با هم مینوشتیم. برنامه هایی که تمرکزشون روی نوشتن فانکشن ها (توابع) بود و برای حل هر سوال سعی میکردیم مساله رو به چند مساله کوچک تر بشکونیم و در هر تابع اون مسائل رو حل میکردیم.

اما این سبک از نوشتن کدها مشکلاتی رو برای ما بوجود میاره. مثلا فرض کنید شما یک برنامه خیلی بزرگ نوشتید که تو این برنامه از استراکچر date استفاده میکنید که شامل day، month، year هستش و تو کل برنامه بارها از این استراکچر استفاده کنید. حالا فرض کنید به هر  دلیلی تصمیم میگیرید که ساختار استراکچرتون رو عوض کنید و به جای روز، ماه و سال با یه متغیر timestamp کار کنید. چه فاجعه ای اتفاق می افته؟! باید برید و تک تک دستوراتی که با date کار کردید رو پیدا کنید و ودستوراتش رو آپدیت کنید. این کار وقت و زمان زیادی از شما میگیره. اما این تنها عیب برنامه نویسی رویه ای نیست، کوتاه اگر بخوام بگم باید به این نکته اشاره کنم که در برنامه نویسی رویه ای کنترل درستی روی داده های دریافتی از کاربر نداریم. یعنی ممکنه کاربر یک عدد منفی برای روز وارد کنه. شاید بگید خب با یه if ساده چک میکنیم که آیا کاربر عدد درست رو وارد کرده یا نه که باید در جواب گفت که شما همیشه باید این شرط رو چک کنید و اگه یه بار فراموش کنید موقع دریافت ورودی این شرط رو چک کنید ممکنه داده اشتباه وارد برنامتون بشه.

برنامه نویسی شی گرا

 
اما شی گرایی چیه که مشکل برنامه نویسی رویه ای رو حل میکنه؟
شی گرایی در واقع  همین چیزیه که ما دور و برمون میبینیم. یعنی اشیا! هر شی که باهاش سر و کار داریم یه سری مشخصات داره (مثل رنگ، اندازه و… ) و یه سری رفتارها ازش سر میزنه (مثلا اگه زنگ خونه رو بزنی به صدا در میاد، یا اگر فرمون ماشین رو به سمت راست بچرخونی ماشین به سمت راست میپیچه) تو برنامه نویسی به مشخصاتی که باهاش شی مون رو توصیف میکنیم میگیم پروپرتی (property) و رفتارهایی که ازش سر میزنه میگیم (method). حالا به مجموعه پروپرتی (که میشه همون متغیرهامون) و متد (که در واقع فانکشنمونه) میگیم class. در برنامه نویسی شی گرا تمرکز ما روی ساخت کلاسهاست.
 
برای درک بهتر مفهوم شی گرایی با یک مثال از دنیای واقعی شروع میکنم. به سلول زیر نگاه کنید
سلول

اگه من از سلول بپرسم که سلول جان! شما داخلت چی داری؟ سلول بر میگرده و میگه به تو چه!

میگه به تو چه که من داخلم چی دارم، من یک دروازه ای در اختیارت قرار میدم (تو برنامه نویسی بهش میگیم interface) و تو از طریق این دروازه به من ورودی بده، اگه غذا دادی، ازت قبول میکنم و پشت بندش یه سری کارها انجام میدم و و اگه به من سم دادی کلا پسش میزنم و وارد سلول نمیکنم:

سلول - interface
برنامه نویسی شی گرا هم همین ایده رو دنبال میکنه. یعنی میخواد کاری کنه که به شما اجازه مستقیم به متغیر day رو نده. چون اگه از خارج از کلاس بشه مستقیما با این متغیر کار کرد ممکنه اشتباهی یک مقدار منفی وارد کلاس بشه. راه حل چیه؟ یه interface در اختیارت قرار میده که در واقع همون تابع است. میگه از طریق تابع درخواستت رو به من بده، من توی تابع بررسی میکنم که آیا درخواستت معتبره یا نه. اگه معتبر بود مقدار day رو تغییر میدم، معتبر نبود هم که هیچی.
 
پس بیا یه جمع بندی تا اینجا داشته باشیم:
در برنامه نویسی رویه ای تمرکز ما روی فانکشنهاست و متغیرهایی که داریم مستقل از فانکشنها تعریف میشن. اما توی شی گرایی تمرکز ما روی کلاسهاست. در واقع توی کلاس ما متغیرها و توابع مربوط به شی‌مون (که از این به بعد بهش میگیم object) رو داریم. و جوری پیاده سازی میکنیم که اجازه ندیم از خارج از کلاس به متغیرهای داخل کلاس (که گفتیم اسمشون پروپرتیه) دسترسی داشته باشن، و اگه قراره بهشون دسترسی داشته باشیم باید  از طریق interfce که همون متدمون هست این کار انجام بشه

اصول برنامه نویسی شی گرا

4 اصل در برنامه نویسی شی گرا داریم:

انتزاع، بسته بندی، وراثت، چندریختی.

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

 

abstract - انتزاع در شی گرایی

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

encapsulation - بسته بندی در شی گرایی

این اصل در واقع میگه که باید پیچیدگی برنامه از چشم بقیه پنهان بشه.

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

توی شی گرایی هم همینه، ما در واقع پیچیدگی های یک آبجکت رو از چشم بقیه پنهان میکنیم که امکان خرابکاری پیش نیاد. این موضوع رو توی ویدیویی که در یوتیوب منتشر کردم بهتر توضیح دادم

inheritance- وراثت در شی گرایی

وراثت دقیقا همون چیزیه که تو دنیای واقعی وجود داره. پروپرتی ها و متدها از والد به فرزند منتقل میشه. یعنی من میتونم یه کلاس داشتم به اسم parent و یه کلاس داشته باشم به اسم child که کلاس دومی از کلاس اولی به ارث میبره. البته توی کلاس parent میتونید دقیقا کنترل داشته باشید که چه چیزی به ارث برده بشه چه چیزی نه. مفهوم کلیش همینه اما باید پیاده سازی و نکاتش رو یاد بگیرید

polymorphism- چندریختی در شی گرایی

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

اگه بخوام در مورد overloading مثال بزنم اینجوری میتونم بگم که شما میتونید یه متد به اسم sum داشته باشی با دو تا پارامتر ورودی و یه تابع دیگه با همون اسم sum داشته باشی با 3 تا پارامتر ورودی. کامپایلر موقع فراخوانی تابع خودش تشخیص میده که از کدوم تابع استفاده کنه.

پیاده سازی

در ادامه میخوام خیلی ساده با هم یک کلاس تعریف کنیم و از اون کلاس استفاده کنیم. به نحوه تعریف کلاس زیر دقت کنید:

تو این کلاس پروپرتی ها و متدها رو پیدا کنید!
سه تا پروپرتی day, mont, year داریم و دو تا متد set_date و print_date که فعلا پیاده سازی نکردیم.
خب این که ساده بود. حالا کد زیر رو ببینید:

فکر کنم میتونید حدس بزنید چه اتفاقی داره میوفته. birthday در واقع یک آبجکت از کلاس Date تعریف میشه و برای دسترسی به متدها و پروپرتیهاش (مثل استراکچرها) از دات (نقطه) استفاده میکنیم. اما آیا خط دوم درسته؟ آیا میتونم خارج از کلاس day دسترسی داشته باشم؟ نه چرا؟

ما اومدیم از کلاسها استفاده کنیم کسی نتونه به داده های ما به صورت مستقیم درسترسی پیدا کنه. (مشکل عدد منفی برای day رو به یاد بیارید) پس من باید از طریق متد set_date این کار رو انجام بدم. یعنی به این متد مقادیرم رو ارسال میکنم و تو این متد بررسی میشه آیا مقدارم معتبره یا نه و اگه معتبر بود مقداردهی میکنه. حالا بگید این کد درسته یا نه:

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

توی کلاس set_date برای اینکه شلوغ نشه شرطها رو ننوشتمو شما میتونید شرطهای مربوط به معتبر بودن تاریخ رو خودتون بنویسید. حالا بیاید به این سوالاتی که در ادامه میپرسم فکر کنید و جوابهاش رو کامنت کنید و منم جوابهاتون رو بررسی میکنم و اشتباهتون رو بهتون میگم:

چند سوال

1- آیا منطقیه که پروپرتی های یک کلاس رو public تعریف کنیم؟
2- آیا منطقیه که متد یک کلاس رو private تعریف کنیم؟
3- آیا منطقیه که همه متدهای یک کلاس رو private تعریف کنیم؟
4- در مثال بالا اگه بخوام فقط به مقدار day دسترسی داشته باشم چیکار کنم؟
5- در مثال بالا اگه بخوام فقط مقدار day رو تغییر بدم چیکار کنم؟
 

جواب سوالات بالا رو کامنت کنید و اگه دوست داشتید میتونید در قسمت دوم آموزش شی گرایی که در یوتیوب منتشر کردم جواب این سوالات رو ببینید. (آخر ویدیو)

نمونه سوالات و پروژه های شی گرایی

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

این آموزش براتون مفید بود؟ میتونید بقیه آموزشهای من رو هم اینجا ببینید

نمونه سوالات سی پلاس پلاس

کلی سوال برنامه نویسی!

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

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