1. مهمان گرامی، جهت ارسال پست، دانلود و سایر امکانات ویژه کاربران عضو، ثبت نام کنید.
    بستن اطلاعیه

يك بام و دو هوا

شروع موضوع توسط minaaa ‏23/10/11 در انجمن C #C++

  1. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,773
    تشکر شده:
    6,457
    امتیاز دستاورد:
    113
    [​IMG]


    يكي از مفاهيم اصلي شيء‌گرايي، مفهوم وراثت است. به اين معني كه يك كلاس مي‌تواند از كلاس ديگري مشتق شده يا اصطلاحا ارث‌بري كند. در تجزيه و تحليل شي‌گرايي مفاهيمي وجود دارند كه همگي در يك‌سري خصوصيات و رفتار مشترك هستند. مثلا در يك سيستم ثبت‌نام دانشجويي، اساتيد و دانشجويان و مسوولان آموزش همگي داراي برخي صفات خاص (كه اختصاصا مربوط به هريك از اين موجوديت‌هاست) هستند و يك‌سري صفات بين همه آنها مشترك است، مثلا نام و نام خانوادگي و برخي خصوصيات و روابط ديگر. حالا قرار است سيستم را پياده‌سازي كنيد، آن گاه براي هر موجوديت بايد تمام خصوصيات مربوط به آن را بنويسيد. آيا منطقي است براي هر موجوديت خصوصيات مشترك را دوباره بنويسيم؟ جواب منفي است!


    اينجاست كه شي‌گرايي به كمك شما مي‌آيد و با كنار هم قرار دادن خصوصيات و رفتارهاي مشترك يك كلاس سطح بالا ايجاد مي‌كند و باقي كلاس‌ها از اين كلاس به ارث برسند و فقط شامل خصوصيات اختصاصي خود هستند و خصوصيات مشترك مثل نام و نام‌خانوادگي را از كلاس پدر خود ارث مي‌برند.

    در زبان C++ يك مفهوم وجود دارد، به نام ارث‌بري چندگانه. يعني چه؟

    در مثال بالا يك كلاس از يك كلاس سطح بالاتر از خود به ارث رسيده است. در بعضي مواقع يك كلاس به جاي اين‌كه از يك كلاس به ارث برسد. نياز است كه از چند كلاس به ارث برسد و از هر كدام يك‌سري خصوصيات را به ارث ببرد؛ مثلا يك كلاس Human داريم كه خصوصيات يك انسان را در خود نگه مي‌دارد. يك كلاس Worker داريم كه علاوه بر خصوصيات Human يك‌سري خصوصيات اختصاصي هم دارد. حالا كلاس ديگري داريم به نام Musician خب اين كلاس علاوه بر خصوصيات كلاس Human داراي خصوصيات Worker هم است. پس كلاس Musician بايد از دو كلاس Human و Worker به ارث برسد. به اين مي‌گويند ارث‌بري چندگانه، يعني يك كلاس همزمان از چند كلاس به ارث برسد.

    بسيار خب، در زبان‌هاي شي‌گراي مدرن مانند C# و جاوا اين مبحث ديگر وجود ندارد. يعني يك كلاس نمي‌تواند از يك يا چند كلاس به ارث برسد، اما بايد اين را يك ضعف در اين زبان‌ها قلمداد كرد و آيا ايده طراحان اين زبان‌ها براي حذف چه ويژگي‌اي بوده‌ است و چه راه‌حلي براي نبود اين ويژگي ارائه داده‌اند. اينجاست كه بحث Interface‌ها مطرح مي‌شوند. Interface در لغت به معني رابط است، اما دقيقا به چه معني است. يك تعريف كلي براي Interface اين است كه يك Protocol (قانون) براي يك‌سري كلاس است. يعني يك كلاس از قواعد خاصي تبعيت كند. يعني چه؟

    برمي‌گرديم به همان ارث‌بري. يكي از اهداف ارث‌بري جلوگيري از كد‌هاي تكراري است. هدف ديگر دادن خط‌مشي به كلاسي كه از يك كلاس ديگر به ارث رسيده است، يعني يك كلاس بداند چه خصوصيات و رفتاري را بايد داشته باشد كه اين رفتار‌ها عمومي هستند. اينها در زمان طراحي كلاس‌ها هستند.

    كاربرد ديگر زمان استفاده از يك كلاس است. فرض كنيد در همان مثال بالا هر كس بايد در دانشگاه ثبت‌نام كند چه استاد باشد چه دانشجو. حالا در برنامه شما قرار است يك متد بنويسيد كه اطلاعات يك دانشجو را بگيريد و آن را ثبت‌نام كند و همين‌طور يك استاد را. راه‌حل چيست؟ شما 2 متد بنويسيد. يكي دانشجو را ثبت كند يكي استاد را و اگر براي مسوول آموزش هم خواستيم مي‌نويسيم اين كار يك مقدار كد نويسي ما را زياد مي‌كند. راه‌حل اين است كه يك متد بنويسيم كه يك شيء از يك كلاس پدر دانشجو و استاد را بگيرد و عمل ثبت‌نام را انجام دهد. با اين كار اگر موجوديت ديگري وارد سيستم شد نيز مي‌تواند با استفاده از همان متد قبلي ثبت‌نام شود. خب برگرديم به همان رابط. براي راحتي فهم مي‌توان رابط را يك كلاس سطح بالا دانست.

    اما رابط يك تفاوت باكلاس دارد آن‌ هم اين است كه پياده‌سازي نشده‌ و درواقع يك الگوست. كلاس‌هايي كه از يك رابط به ارث مي‌رسند، آن رابط را پياده مي‌كنند. يعني متد‌ها و خصوصيات آن را مطابق دلخواه خود پياده‌سازي مي‌كنند. رابط مانند يك كلاس Abstract است، اما تفاوت‌هايي دارند. يكي از تفاوت‌هاي عمده آنها در اين است كه در زبان C#‌ يك كلاس از چند رابط مي‌تواند ارث‌بري كند، ولي تنها از كلاس مي‌تواند ارث‌بري داشته باشد. پس مي‌توان نتيجه گرفت كه يك كلاس از يك كلاسAbstract ارث‌بري دارد و از چند رابط هم مي‌تواند ارث‌بري داشته باشد. تفاوت ديگر آنها در اين است كه اجزاي يك رابط پياده‌سازي نمي‌شود، ولي اجزاي يك كلاس Abstract مي‌تواند پياده‌سازي شوند.