PDA

توجه ! این یک نسخه آرشیو شده می باشد و در این حالت شما عکسی را مشاهده نمی کنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : مفاهيم شئ گرايی در #c



Borna66
08-10-2010, 12:50 AM
دنيای برنامه نويسی امروزه بر مفهوم شئ گرايی استوار است. شئ گرايی به زبان ساده يعنی دنيا را آنطور ببنيم که هست! زبان #C يکی از بهترين زبانهايی است که دارای تمامی امکانات جهت پياده سازی مفاهيم اصيل شئ گرايی است. در اين مقاله با برخی مفاهيم مهم شئ گرايی از ديدگاه زبان #C آشنا می شويم. فراموش نکنيد که قبل از خواندن اين مقاله شما بايد با مفهوم کلاس و شئ آشنا باشيد.
ا
شئ گرايی (OOP) در #C بر چند پايه استوار است که به قرار زيرند:

- Inheritance
- Encapsulation
- Polymorphism
- Abstraction
- Interface
اكنون به توضيح مختصر هر يک می پردازيم.

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


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

فرض کنيد سوار ماشينی هستيد که به سرعت در حرکت است! در مسيری که می رويد ماشين پدر نامزدتان از روبرو به شما نزديک می شود و سعی می کنيد سريع ترمز بگيريد تا برخورد نكنيد. اگر قرار باشد که بدانيد بعد از فشار دادن پدال ترمز چه عملياتی انجام می شود تا ترمز گرفته شود، ديگر بايد از ازدواج قطع اميد کنيد. ولی اگر تنها بدانيد که با فشار دادن پدال، ترمز گرفته می شود شما خوشبخت خواهيد شد. در واقع ما در اينجا کار ترمز گرفتن ماشين را به صورت يک کپسول آماده در نظر می گيريم. هدف Encapsulation اين است که ما را از پرداختن به ريز موضوعات رها کند و اشياء را به صورت يک جعبه سياهی بدانيم که به ازای يک ورودی خاص خروجی خاصی می دهند. اگر می خواهيم کدهای ما نيز اين مورد را رعايت کنند بايد سعی کنيم نگاه کپسولی به اشياء و عملکرد آنها داشته باشيم. در #C برای کپسوله کردن از Access Modifierهای protected ،private و public استفاده می شود.


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


Abstraction
تجريد يا مجرد سازی! به كلاسی مجرد گفته می شود كه پياده سازی متدها در آن انجام نمی شود! بر خلاف انسانها كه مجرد تعريف ديگری برايشان دارد! حال سئوالی پيش می آيد كه اگر کلاسی داشته باشيم که نخواهيم پياده سازی متدها را در آن انجام بديم، از آن كلاس چه استفاده ای می کنيم؟ برای پاسخ به اين سئوال شرايط زير را در نظر بگيريد:

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

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


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

حالا اين اينترفيس در كجا به كار می آيد؟ اگر با ++C کار کرده باشيد ( در آن صورت کارتان خيلی درست می باشد!!!) با واژه ارث بری چند گانه آشنا هستيد. ولی احتمالا شنيديد که جاوا و #C از ارث بری چندگانه پشتيبانی نمی کنند. (يعنی يک کلاس از چند کلاس ديگر به ارث ببرد). گاهی لازم داريم از چند کلاس به ارث ببريم. راه حلش اين است که از اينترفيس ها استفاده کنيم. ولی بدانيد که اگر از اينترفيسی به ارث برديد بايد تمام متدهای آن را پياده سازی کنيد. يک کلاس می تواند از n تا اينترفيس و تنها يک کلاس به ارث ببرد.