PDA

View Full Version : تفاوت protected , private , public



alireza es
شنبه 11 مرداد 1393, 15:36 عصر
با عرض سلام.علت اینکه تو برنامه نویسی شی گرا سه سطح دسترسی برای اعضای یک کلاس تعریف میکنیم چیه؟برای مثال من میتونم تمامی اشیا رو به صورت
public در بیارم.ایا این کار تاثیری در خروجی خواهد داشت یا این که تمامی مسائل برای برنامه نویس هست؟من برنامه نویس وقتی لازم باشه یه متد رو خارج از یک کلاس
استفاده کنم استفاده میکنم و وقتی لازم نباشه استفاده نمیکنم !! چه دلیلی برای ایجاد سه سطح دسترسی برای اعضا وجود داره؟

ببخشین میدونم احتمالش خیلی زیاده تکراری باشه اما وقتی سرچ کردم تایپک های مشابه به توضیح این سطوح دسترسی پرداخته بودند نه سوال من

tux-world
شنبه 11 مرداد 1393, 16:22 عصر
شی گرایی یکی از مهم ترین و کاربردی ترین مباحث در برنامه نویسی پیشرفته و ساخت یافته می باشد .
در حقیقت شی گرایی نوعی طرز تفکر خاص در پیاده سازی برنامه هاست ، به عبارتی برنامه نویس با بخش های مختلف برنامه به همان صورتی که با اشیا در دنیای واقعی رفتار می کند ، ارتباط برقرار می نماید .کلاس ها مهم ترین جزء شی گرایی هستند و در حقیقت کلاس ، تولید کننده یک شی محسوب می شود .حالا باید پرسید که شی چیست ؟
یک شی می تواند یک موجودیت فیزیکی باشد ، مانند یک کتاب ، یک صندلی. شما می توانید یک کتاب را توصیف کنید ، آنرا بخوانید و آنرا بخرید. یک شی می تواند یک موجودیت غیر فیزیکی و غیر قابل لمس (intangible) باشد ، مانند یک کار یا زمان. با اینکه یک کار چیزی است که شما بصورت فیزیکی نمی توانید آنرا لمس کنید اما می توانید آنرا توصیف کنید ، روی آن بحث کنید ، آنرا انجام بدهید و تکمیل کنید. هر چیزی که بتوانید آنرا توصیف کنید می تواند به عنوان یک شی در نظر گرفته شود.
یک کتاب ، یک صندلی ، یک کار و هر شی در دنیا واقعی بوسیله دو گروه از خصوصیات مشخصی می شوند :


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


هر سه بخش فوق می توانند Public , Private یا Protected باشد .((البته INTERNAL هم هست)).حالا با نوشتن یک کلاس به نوع دسترسی ها می پردازم .کلاس((CLASS))کلاس ها همان نوع داده تجریدی یا انتزاعی (Abstract) هستند. به عبارتی یک نوع داده هستند که توسط برنامه نویس برای کار با داده ها و توابع و رویدادهای مختلفی تعریف می شوند. برای تعریف کلاس از الگوی زیر پیروی می کنیم :

1. class className
2. {
3. // Define private variables & functions
4. public:
5. // Define public variables & functions
6. private:
7. // Define private variables & functions
8. protected:
9. // Define protected variables & functions
10. } objectsame; // Declare Objects

همانطور که در بالا آمد، برای تعریف یک کلاس از کلمه کلیدی class استفاده می کنیم و نامی را در ادامه برای آن تعیین می کنیم .
متغیرها و توابع مربوط به class در درون بلوک آکولاد قرار خواهند گرفت. فرض بر این است که دسترسی داده ها و توابع private است مگر اینکه نوع دسترسی صراحتا اعلام شود .
داده ها و توابعی که طبق سطر 3 تعریف شوند بطور پیش فرض از سطح دسترسی private برخوردار خواهند بود زیرا چیزی برای آنها تعریف نشده است کما اینکه در سطر 6 این سطح دسترسی کاملا بیان شده است .
سطح دسترسی private به این معناست که که داده ها و توابع تعریفی در این سطح، فقط در این class شناخته می شوند و در خارج از کلاس هیچگونه دسترسی به آنها وجود ندارد و تمامی عملیات روی آنها فقط باید در همان class تعریف شوند که همان مفهوم Encapsulation یا محرمانگی و بسته بندی را پیاده سازی می کنند .((در مورد دسته بندی ، جندریختی و ارث بری)) بعد توضیح خواهم داد.
در سطر 4 می توان داده ها و توابعی را که دارای سطح دسترسی public یا عمومی هستند را تعریف نمود و این بدین معناست که داده ها و توابع با این سطح دسترسی هم در داخل و هم در خارج از class قابل دسترسی هستند .
در سطر 8 نیز نوع دسترسی protected ذکر شده، یعنی کلاس هایی که از این کلاس به ارث برده می شنود می توانند به این قسم از داده ها و توابع دسترسی داشته باشند .
در سطر 10 و در خارج از محدوده کلاس نیز باید اشیائی را برای دسترسی به اعضای class خود ایجاد نماییم که به ذکر نام یا نام هایی که با کاما از هم جدا می شوند بسنده می کنیم. دقت داشته باشید که ایجاد شی از کلاس را می توان در درون تابع main نیز انجام داد .
در ساختمان داده طرز ساخت یک شی را یاد گرفتیم اما در پست های بعدی طرز ساخت یک شی و مقدار دهی به ان را توضیح خواهم داد.

alireza es
شنبه 11 مرداد 1393, 16:33 عصر
داداش خیلی ممنون.دو سه تا نکته وجود داشت که تازه یاد گرفتم.
اما کلا سوال من این نبود.
اگه ممکنه یه بار دیگه پست اولو بخونید.سوال من این بود که سطوح دسترسی private ,protected ,public به جز تفاوت هایی که کامل تو پستتون توضیح دادین
تفاوت های دیگه ای هم دارند؟مثلا نحوه قرار گرفتنشون در حافظه یا چیزای دیگه که نمیدونم :لبخندساده:
اگه نه پس من اگه بیام تمامی متد ها و متغیر هارو public بگیرم مشکلی نباید پیش بیاد چون هر وقت لازم باشه اونارو استفاده میکنم و اگه لازم نباشه استفاده نمیکنم

2020s1371
یک شنبه 12 مرداد 1393, 00:09 صبح
چه دلیلی برای ایجاد سه سطح دسترسی برای اعضا وجود داره؟

فکر کنم بهترین دلیلش پنهان سازی اطلاعات باشه و مبحث وراثت

sa1378
یک شنبه 12 مرداد 1393, 14:39 عصر
در بعضی برنامه ها ممکنه نخواین کسی اصلاعات یک کلاس رو تغییر بده برای همین private تعریف میکنین و اگه بخواین فقط فرزند های کلاس تغییرش بدن protected میشه
ولی برای منم سواله
برنامه ای که کدهاشو فقط خودمون مینویسیم چرا نباید اجازه دسترسی رو به خودمون بدیم
خب همه public باشه که راحت تره
دیگه لازم نیست یه تابع get هم برای هر متغیر تعریف کرد

2020s1371
یک شنبه 12 مرداد 1393, 15:17 عصر
در بعضی برنامه ها ممکنه نخواین کسی اصلاعات یک کلاس رو تغییر بده برای همین private تعریف میکنین و اگه بخواین فقط فرزند های کلاس تغییرش بدن protected میشه
ولی برای منم سواله
برنامه ای که کدهاشو فقط خودمون مینویسیم چرا نباید اجازه دسترسی رو به خودمون بدیم
خب همه public باشه که راحت تره
دیگه لازم نیست یه تابع get هم برای هر متغیر تعریف کرد


موقعی که شما از وراثت میخواید استفاده کنین چجوری باید از به ارث رسیدن برخی موارد جلوگیری کنید؟؟

+
تو یک پروژه تک نفری این حرفتون درست ولی تو یک پروژه تیمی چی؟؟

sa1378
یک شنبه 12 مرداد 1393, 19:46 عصر
موقعی که شما از وراثت میخواید استفاده کنین چجوری باید از به ارث رسیدن برخی موارد جلوگیری کنید؟؟

+
تو یک پروژه تک نفری این حرفتون درست ولی تو یک پروژه تیمی چی؟؟
حرفتون درسته
ولی منم منظورم همون تک نفری بود چون من که تاحالا گروهی کار نکردم نمیدونم

tux-world
یک شنبه 12 مرداد 1393, 20:09 عصر
این موضوع هیچ ربطی به پروژه تیمی داشتن یا نداشتن نداره شما وقتی که دارید برنامه نویسی میکنید چیکار میکنید؟ از ب بسم الله شروع میکنید به کد زنی؟؟؟ نمیایید اول منطقش رو در بیارید؟ کلا از اصول ساخت یافته چیزی تا الان فهمیدین؟
وقتی که میخوایید برنامه نویسی کنید اول باید تحلیلش کرد منطقش رو در اورد قسمتهای مختلف رو تقسیم بندی کرد و و و ..
خوب تو این بین شما نیاز دارید که از قسمتهای مختلف برنامه پروژه های دیگتون استفاده کنید. ما که قرار نیست با کپی پیست کردن کارا رو پیش ببریم برای همین اول اون رو به صورت یک کلاس در میاریم و شرط و شروط میزاریم مثل یه مامور راهنمایی رانندگی (چیز بهتری به ذهنم نرسید) میگیم نوع استفاده و دسترسی از توابع و کلاسهای موجود کلاس به چه شکل باشه. با این همه کار شما با رعایت مواردی از قبیل public و یا private میتونین از اشتباه هات کد نویسی دخل و تصرف های بیجا و یا نا آگاهانه خودداری کنید و مثل یه برنامه نویس با کلاس و یا حتی مثل یه معمار که کل برنامش مهندسی شدست رفتار کنید

alireza es
یک شنبه 12 مرداد 1393, 20:20 عصر
این موضوع هیچ ربطی به پروژه تیمی داشتن یا نداشتن نداره شما وقتی که دارید برنامه نویسی میکنید چیکار میکنید؟ از ب بسم الله شروع میکنید به کد زنی؟؟؟ نمیایید اول منطقش رو در بیارید؟ کلا از اصول ساخت یافته چیزی تا الان فهمیدین؟
وقتی که میخوایید برنامه نویسی کنید اول باید تحلیلش کرد منطقش رو در اورد قسمتهای مختلف رو تقسیم بندی کرد و و و ..
خوب تو این بین شما نیاز دارید که از قسمتهای مختلف برنامه پروژه های دیگتون استفاده کنید. ما که قرار نیست با کپی پیست کردن کارا رو پیش ببریم برای همین اول اون رو به صورت یک کلاس در میاریم و شرط و شروط میزاریم مثل یه مامور راهنمایی رانندگی (چیز بهتری به ذهنم نرسید) میگیم نوع استفاده و دسترسی از توابع و کلاسهای موجود کلاس به چه شکل باشه. با این همه کار شما با رعایت مواردی از قبیل public و یا private میتونین از اشتباه هات کد نویسی دخل و تصرف های بیجا و یا نا آگاهانه خودداری کنید و مثل یه برنامه نویس با کلاس و یا حتی مثل یه معمار که کل برنامش مهندسی شدست رفتار کنید

من یه شایعاتی در مورد نحوه قرار گرفتن متغیر های public و private و protected تو رم و اینک با هم فرق دارن شنیده بودم.
ولی انگار فرقی ندارن باهم و فقط برای خوانایی کد این کارو میکنن

tux-world
دوشنبه 13 مرداد 1393, 02:15 صبح
خوانایی؟؟؟؟ این همه داستان و روایت تعریف کردیم چیزی متوجه نشدید؟ بهتره دوباره تاپیک رو از اول مطالعه بفرمایید !! از ارسال اسپم هم خودداری کنید !!

2020s1371
دوشنبه 13 مرداد 1393, 04:31 صبح
این موضوع هیچ ربطی به پروژه تیمی داشتن یا نداشتن نداره شما وقتی که دارید برنامه نویسی میکنید چیکار میکنید؟ از ب بسم الله شروع میکنید به کد زنی؟؟؟ نمیایید اول منطقش رو در بیارید؟ کلا از اصول ساخت یافته چیزی تا الان فهمیدین؟
وقتی که میخوایید برنامه نویسی کنید اول باید تحلیلش کرد منطقش رو در اورد قسمتهای مختلف رو تقسیم بندی کرد و و و ..
خوب تو این بین شما نیاز دارید که از قسمتهای مختلف برنامه پروژه های دیگتون استفاده کنید. ما که قرار نیست با کپی پیست کردن کارا رو پیش ببریم برای همین اول اون رو به صورت یک کلاس در میاریم و شرط و شروط میزاریم مثل یه مامور راهنمایی رانندگی (چیز بهتری به ذهنم نرسید) میگیم نوع استفاده و دسترسی از توابع و کلاسهای موجود کلاس به چه شکل باشه. با این همه کار شما با رعایت مواردی از قبیل public و یا private میتونین از اشتباه هات کد نویسی دخل و تصرف های بیجا و یا نا آگاهانه خودداری کنید و مثل یه برنامه نویس با کلاس و یا حتی مثل یه معمار که کل برنامش مهندسی شدست رفتار کنید
بنظر من همین دلایلی هم که فرمودید در مورد پروژه تیمی صدق میکنه! بخصوص اینکه از اشتباهاتی که ممکنه رخ بده جلوگیری میکنه..
درضمن دعوا که نداریم... حرف شما برای ماحجته... ولی این یه نظر شخصیه من بود... به موضوع هم ربطی نداره...بگذریم

tux-world
سه شنبه 14 مرداد 1393, 14:53 عصر
کپسوله سازی

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

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

درون یک شی (کد وداده ها) یا هردو ممکن است برای آن شی محلی (خصوصی/Private) یا عمومی (Public) باشند.کد یا داده های محلی فقط توسط بخش دیگری از شی شناخته شده و قابل دست یابی هستند.

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

چند ریختی

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

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

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

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

وراثت

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

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

بنابراین مکانیزم وراثت به یک شی امکان می دهد تا نمونه خاص از یک حالت عمومی تر باشد.

Inheritance ارث بری

پدر و فرزندی را در نظر بگیرید . هر پدری مشخصات فردی به خصوصی دارد . فرزند وی می تواند همه خصوصیات او را به ارث برد و خصوصیتهای دیگری نیز داشته باشد که پدرش ندارد . این یعنی ارث بری !

در برنامه نویسی شی گرا از مفهوم ارث بری استفاده های زیادی می شود . قابلیت استفاده دوباره از کد (Reusability) یکی از مزیات اصلی ارث بری است.

Encapsulation

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

هدف Encapsulationاین است که ما را از پرداختن به ریز موضوعات رها کند و اشیا را به صورت یک جعبه سیاهی بدانیم که به ازای یک ورودی خاص خروجی خاصی می دهند .

در C# برای کپسوله کردن از Access Modifier های Private ، Protected ، Public استفاده شود.

Polymorphism

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

Abstraction

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

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

Interface
اینترفیس در برنامه نویسی همانند همان کلاس است تنها با این تفاوت که هیچکدام از اعضای آن پیاده سازی نمی شوند . در واقع یک اینترفیس گروهی از متدها ، خصوصیات ، رویدادها و Indexer ها هستند که در کنار هم جمع شده اند. اینترفیس ها را نمی توان Instantiate (وهله سازی) کرد (یعنی نمی توان وهله ای از یک اینترفیس ایجاد کرد !) . تناه چیزی که اینترفیس دارا می باشد امضای (signature) تمامی اعضای آن می باشد. به ای معنی که ورودی و خروجی متدها ، نوع property ها و ... در آن تعریف می شوند ولی چیزی پیاده سازی نمی شود. اینترفیس ها سازنده و فیلد ندارد. یک اینترفیس نمی تواند Operator Overload داشته باشد و دلیل آن این است که در صورت و جود ویژگی ، احتمال بروز مشکلاتی از قبیل ناسازگازی با دیگر زبانهای .Net مانند VB.Net که از این قابلیت پشتیبانی نمی کند وجود داشت. نحوه تعریف اینترفیس بسیار شبیه تعریف کلاس است تنها با این تفاوت که در اینترفیس پیاده سازی وجود ندارد.

tux-world
سه شنبه 14 مرداد 1393, 14:58 عصر
و مباحث دیگه که خیلی مهمه مفاهیمش رو بدونید عبارتند از موارد زیر:

کپسوله سازی

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

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

درون یک شی (کد وداده ها) یا هردو ممکن است برای آن شی محلی (خصوصی/Private) یا عمومی (Public) باشند.کد یا داده های محلی فقط توسط بخش دیگری از شی شناخته شده و قابل دست یابی هستند.

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

چند ریختی

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

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

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

زبان های برنامه نویسی شی گرای اولیه چون به صورت مفسری بودند از چند ریختی در زمان اجرا پشتیبانی می کردند. ولی چون C++‎‎ کامپایلری است پس هم در زمان اجرا و هم در زمان کامپایل از چند ریختی پشتیبانی می کند.

وراثت

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

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

بنابراین مکانیزم وراثت به یک شی امکان می دهد تا نمونه خاص از یک حالت عمومی تر باشد.

Inheritance ارث بری

پدر و فرزندی را در نظر بگیرید . هر پدری مشخصات فردی به خصوصی دارد . فرزند وی می تواند همه خصوصیات او را به ارث برد و خصوصیتهای دیگری نیز داشته باشد که پدرش ندارد . این یعنی ارث بری !

در برنامه نویسی شی گرا از مفهوم ارث بری استفاده های زیادی می شود . قابلیت استفاده دوباره از کد (Reusability) یکی از مزیات اصلی ارث بری است.

Encapsulation

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

هدف Encapsulationاین است که ما را از پرداختن به ریز موضوعات رها کند و اشیا را به صورت یک جعبه سیاهی بدانیم که به ازای یک ورودی خاص خروجی خاصی می دهند .

در C#‎‎ برای کپسوله کردن از Access Modifier های Private ، Protected ، Public استفاده شود.

Polymorphism

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

Abstraction

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

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

Interface
اینترفیس در برنامه نویسی همانند همان کلاس است تنها با این تفاوت که هیچکدام از اعضای آن پیاده سازی نمی شوند . در واقع یک اینترفیس گروهی از متدها ، خصوصیات ، رویدادها و Indexer ها هستند که در کنار هم جمع شده اند. اینترفیس ها را نمی توان Instantiate (وهله سازی) کرد (یعنی نمی توان وهله ای از یک اینترفیس ایجاد کرد !) . تناه چیزی که اینترفیس دارا می باشد امضای (signature) تمامی اعضای آن می باشد. به ای معنی که ورودی و خروجی متدها ، نوع property ها و ... در آن تعریف می شوند ولی چیزی پیاده سازی نمی شود. اینترفیس ها سازنده و فیلد ندارد. یک اینترفیس نمی تواند Operator Overload داشته باشد و دلیل آن این است که در صورت و جود ویژگی ، احتمال بروز مشکلاتی از قبیل ناسازگازی با دیگر زبانهای .Net مانند VB.Net که از این قابلیت پشتیبانی نمی کند وجود داشت. نحوه تعریف اینترفیس بسیار شبیه تعریف کلاس است تنها با این تفاوت که در اینترفیس پیاده سازی وجود ندارد.

omid_kma
پنج شنبه 16 مرداد 1393, 00:01 صبح
دوست عزیز این چیزایی که گذاشتین بعضی هاشون اصلا داخل ++C درست نیست .
مثلا ما توی ++C چیزی به اسم Interface نداریم که بجاش multi inheritance هست که نمیشه گفت ربط زیادی به interface داره !
نحوه تعریف abstract هم که به این شکل نیست یعنی کلمه کلیدی به اسم abstract توی ++C نداریم


گه ممکنه یه بار دیگه پست اولو بخونید.سوال من این بود که سطوح دسترسی private ,protected ,public به جز تفاوت هایی که کامل تو پستتون توضیح دادین
تفاوت های دیگه ای هم دارند؟مثلا نحوه قرار گرفتنشون در حافظه یا چیزای دیگه که نمیدونم
نه حافظه و رم فرقی نداره
چیزی که برای کامپایلر مهمه اینه که هر کدوم از این توابع یا متغیرها چه جاهایی و چقدر استفاده شدن public private تاثیر خاصی نداره اگر توابع زیاد استفاده شده باشن و قابل محاسبه باشن مقدارشون حساب میشه و داخل کد گذاشته میشن یا اگر تابعی داخل کلاس استفاده نشه کلا حذف میشه و چیزای دیگه .
یک نکته دیگه این که اصولا بهتره اگر کسی دنبال سرعت بالاتر هست از inheritance های با عمق زیاد استفاده نکنه چون کامپایلر علاوه بر این که ممکنه نتونه به خوبی کد رو optimize کنه زمان کامپایل هم به شدت زیاد میشه .

tux-world
پنج شنبه 16 مرداد 1393, 01:32 صبح
من زیاد با شی گرایی تو سی پلاس آشنا نیستیم ولی فرق آنچنانی نمیکنن. به هر حال ممنون بابت تذکر و نکته مهمی که فرمودید. در کل در مورد مبحث inheritance ها اینا به صورت ناخواسته یه خورده ممکنه عمق زیادی داشته باشن. راه حل مناسبش چیه؟ منظورم این هستش که برای اینکه از عمق مناسبی استفاده بشه ترجیح داده میشه که از کلاسهای واسط استفاده بشه؟

ProgramYL
پنج شنبه 16 مرداد 1393, 10:34 صبح
دوست عزیز این چیزایی که گذاشتین بعضی هاشون اصلا داخل ++C درست نیست .
مثلا ما توی ++C چیزی به اسم Interface نداریم که بجاش multi inheritance هست که نمیشه گفت ربط زیادی به interface داره !
...


تا جاییکه من کار کردم، در ++C هم اینترفیس وجود داره و در مقابلش پیاده سازی (implementation)، اینترفیس واسطه ای هست که در اختیار مشتری ها (نویسنده های تابع main) قرار میگیره، به این صورت نویسنده های سورس کد از چگونگی اجرا و پیاده سازی (implementation) تابع های کلاس اطلاع ندارند و فقط می تونن از توایع ایجاد شده که توسط نویسنده های کلاس ایجاد میشه استفاده کنن.

تعریف شما از اینترفیس چیه؟

omid_kma
پنج شنبه 16 مرداد 1393, 15:22 عصر
تا جاییکه من کار کردم، در ++C هم اینترفیس وجود داره و در مقابلش پیاده سازی (implementation)، اینترفیس واسطه ای هست که در اختیار مشتری ها (نویسنده های تابع main) قرار میگیره، به این صورت نویسنده های سورس کد از چگونگی اجرا و پیاده سازی (implementation) تابع های کلاس اطلاع ندارند و فقط می تونن از توایع ایجاد شده که توسط نویسنده های کلاس ایجاد میشه استفاده کنن.

تعریف شما از اینترفیس چیه؟
نه منظور من از interface چیزی که شما گفتید نیست منظور چیزیه که داخل زبان ها دیگه مثلا java وجود داره که بصورت خلاصه یکسری تابع و مشخصات مرتبط هستن که پیاده سازی نشدن بعد با استفاده از implement داخل کلاس های دیگه ازشون میشه استفاده کرد
مثلافرض کنید یک interface برای خصوصیات اشیا تعریف می کنید به این شکل :

interface ShapeInterface{


RGB getColor();


int getArea();


void setColor(RGB color);
//....
}





بعد حالا مثلا یک کلاس Rectangle دارید این interface رو implement می کنید و متد هاشو داخل این کلاس تعریف می کنی

class Rectangle implements ShapeInterface
{
RGB color_;
int width;
int height;


RGB getColor(){
return color_;
}
void setColor(RGB color){
color_ = color;
}
int getArea(){
return width*height;
}
}


میشه داخل یک کلاس از بیشتراز یک interface هم استفاده کرد مثل ارث بری چندگانه در ++C

omid_kma
پنج شنبه 16 مرداد 1393, 15:31 عصر
من زیاد با شی گرایی تو سی پلاس آشنا نیستیم ولی فرق آنچنانی نمیکنن. به هر حال ممنون بابت تذکر و نکته مهمی که فرمودید. در کل در مورد مبحث inheritance ها اینا به صورت ناخواسته یه خورده ممکنه عمق زیادی داشته باشن. راه حل مناسبش چیه؟ منظورم این هستش که برای اینکه از عمق مناسبی استفاده بشه ترجیح داده میشه که از کلاسهای واسط استفاده بشه؟
آره میتونه یک راهش کلاس های واسط باشه البته بستگی به برنامه داره .
میشه از شی گرایی هم جاهایی که لازم نیست استفاده نکرد از template meta programming یا functional programming استفاده کرد مثل کاری که داخل هدر Algorithm خود STL انجام شده .