Make your own free website on Tripod.com

دروس مرتبط

 

  صفحه اصلی > مفاهیم کلی شی گرایی > واسطها (Interfaces) مقدماتی

   

 ارث‌بري كلاس‌ها

چند ريختي (Polymorphism)

> واسطها (Interfaces)

          مقدماتی

          پیشرفته

انديكسرها در #C

 
 

واسطها (Interfaces)مقدماتی

در اين درس با واسطها در زبان C# آشنا خواهيم شد. اهداف اين درس بشرح زير مي‌باشند :

      آشنايي با مفهوم كلي واسطها

      تعريف يك واسط

      استفاده از يك interface

      پياده‌سازي ارث‌بري در interface ها

    

واسطها از لحاظ ظاهري بسيار شبيه به كلاس هستند با اين تفاوت كه داراي هيچ گونه پياده‌سازي نمي‌باشند. تنها چيزي كه در interface به چشم مي‌خورد تعاريفي نظير رخدادها، متدها، انديكسرها و يا property ها است. يكي از دلايل اينكه واسطها تنها داراي تعاريف هستند و پياده‌سازي ندارند آنست كه يك interface مي‌توان توسط چندين كلاس يا property مورد ارث‌بري قرار گيرد، از اينرو هر كلاس يا property خواستار آنست كه خود به پياده‌سازي اعضا بپردازد.

حال بايد ديد چرا با توجه به اينكه interface ها داراي پياده‌سازي نيستند مورد استفاده قرار مي‌گيرند يا بهتر بگوئيم سودمندي استفاده از interface ها در چيست؟ تصور كنيد كه در يك برنامه با مولفه‌هايي سروكار داريد كه متغيرند ولي داراي فيلدها يا متدهايي با نامهاي يكساني هستند و بايد نام اين متدها نيز يكسان باشد. با استفاده از يك interface مناسب مي‌توان تنها متدها و يا فيلدهاي مورد نظر را اعلان نمود و سپس كلاسها و يا property هاي مورد از آن interface ارث‌بري نمايند. در اين حالت تمامي كلاسها و property ها داراي فيلدها و يا متدهايي همنام هستند ولي هر يك پياده‌سازي خاصي از آنها را اعمال مي‌نمايند.

نكته مهم ديگر درباره interface ها، استفاده و كاربرد آنها در برنامه‌هاي بزرگي است كه برنامه‌ها و يا اشياؤ مختلفي در تماس و تراكنش (transact) هستند. تصور كنيد كلاسي در يك برنامه با كلاسي ديگر در برنامه‌اي ديگر در ارتباط باشد. فرض كنيد اين كلاس متدي دارد كه مقداري از نوع int بازميگرداند. پس از مدتي طراح برنامه به اين نتيجه مي‌رسد كه استفاده از int پاسخگوي مشكلش نيست و بايد از long استفاده نمايد. حال شرايط را در نظر بگيريد كه براي تغيير يك چنين مسئله ساده‌اي چه مشكل بزرگي پيش خواهد آمد. تمامي فيلدهاي مورتبط با اين متد بايد تغيير داده شوند. در ضمن از مسئله side effect نيز نمي‌توان چشم پوشي كرد.( تاثيرات ناخواسته و غير منتظره و يا به عبارتي پيش بيني نشده كه متغير يا فيلدي بر روي متغير يا فيلدي ديگر اعمال مي‌كند، در اصطلاح side effect گفته مي‌شود.) حال فرض كنيد كه در ابتدا interface اي طراحي شده بود. درصورت اعمال جزئيترين تغيير در برنامه مشكل تبديل int به long قابل حل بود، چراكه كاربر يا برنامه و در كل user برنامه در هنگام استفاده از يك interface با پيادهسازي پشت پرده آن كاري ندارد و يا بهتر بگوئيم امكان دسترسي به آن را ندارد. از اينرو اعمال تغييرات درون آن تاثيري بر رفتار كاربر نخواهد داشت و حتي كاربر از آن مطلع نيز نمي‌شود.  در مفاهيم كلي شيء گرايي، interface ها يكي از مهمترين و كاربردي ترين اجزاء هستند كه در صورت درك صحيح بسيار مفيد واقع مي‌شوند. يكي از مثالهاي مشهود درباره interface ها (البته در سطحي پيشرفته تر و بالاتر) رابطهاي كاربر گرافيكي (GUI) هستند. كاربر تنها با اين رابط سروكار دارد و كاري به نحوه عمليات پشت پرده آن ندارد و اعمال تغييرات در پياده‌سازي interface كاربر را تحت تاثير قرار نمي‌دهد.

از ديدگاه تكنيكي، واسطها بسط مفهومي هستند كه از آن به عنوان انتزاع (Abstract) ياد مي‌كنيم. در كلاسهاي انتزاعي (كه با كلمه كليد abstract مشخص مي‌شدند.) سازندة كلاس قدر بود تا فرم كلاس خود را مشخص نمايد : نام متدها، نوع بازگشتي آنها و تعداد و نوع پارامتر آنها، اما بدون پياده‌سازي بدنه متد. يك interface همچنين مي‌تواند داراي فيلدهايي باشد كه تمامي آنها static و final هستند. يك interface تنها يك فرم كلي را بدون پياده‌سازي به نمايش مي‌گذارد.

از اين ديدگاه، يك واسط بيان مي‌دارد كه : " اين فرم كلي است كه تمامي كلاسهايي كه اين واسط را پياده‌سازي مي‌كنند، بايد آنرا داشته باشند." از سوي ديگر كلاسها و اشياء ديگري كه از كلاسي كه از يك واسط مشتق شده استفاده مي‌كنند، مي‌دانند كه اين كلاس حتماً تمامي متدها و اعضاي واسط را پياده‌سازي مي‌كند و مي‌توانند به راحتي از آن متدها و اعضا استفاده نمايند. پس به طور كلي مي‌توانيم بگوئيم كه واسطها بمنظور ايجاد يك پروتكل (protocol) بين كلاسها مورد استفاده قرار مي‌گيرند. (همچنان كه برخي از زبانهاي برنامه‌سازي بجاي استفاده از كلمه كليدي interface از protocol استفاده مي‌نمايند.)

ابتدای صفحهF

به دليل اينكه كلاسها و ساختارهايي كه از interface ها ارث‌بري مي‌كنند موظف به پياده‌سازي و تعريف آنها هستند، قانون و قاعده‌اي در اين باره ايجاد مي‌گردد. براي مثال اگر كلاس A از واسط IDisposable ارث‌بري كند، اين ضمانت بوجود مي‌آيد كه كلاس A داراي متد Dispose() است، كه تنها عضو interface نيز مي‌باشد. هر كدي كه مي‌خواهد از كلاس A استفاده كند، ابتدا چك مي‌نمايد كه آيا كلاس A واسط IDisposable را پياده‌سازي نموده يا خير. اگر پاسخ مثبت باشد آنگاه كد متوجه مي‌شود كه مي‌تواند از متد A.Dispose() نيز استفاده نمايد. در زير نحوه اعلان يك واسط نمايش داده شده است.

interface IMyInterface

{

void MethodToImplement();

}

در اين مثال نحوه اعلان واسطي با نام IMyInterface نشان داده شده است. يك قاعده (نه قانون!) براي نامگذاري واسطها آنست كه نام واسطها را با "I" آغاز كنيم كه اختصار كلمه interface است. در interface اين مثال تنها يك متد وجود دارد. اين متد مي‌توان هر متدي با انواع مختلف پارامترها و نوع بازگشتي باشد. توجه نماييد همانطور كه گفته شد اين متد داراي پياده‌سازي نيست و تنها اعلان شده است.  نكته ديگر كه بايد به ان توجه كنيد آنست كه اين متد به جاي داشتن {} به عنوان بلوك خود، داراي ; در انتهاي اعلان خود مي‌باشد. علت اين امر آنست كه interface تنها نوع بازگشتي و پارامترهاي متد را مشخص مي‌نمايد و كلاس يا شي‌اي كه از آن ارث مي‌برد بايد آنرا پياده‌سازي نمايد. مثال زير نحوه استفاده از اين واسط را نشان مي‌دهد.

 ابتدای صفحهF

مثال 1-13 : استفاده از واسطها و ارث‌بري از آنها

class InterfaceImplementer : IMyInterface

{

static void Main()

{

InterfaceImplementer iImp = new InterfaceImplementer();

iImp.MethodToImplement();

}

public void MethodToImplement()

{

Console.WriteLine("MethodToImplement() called.");

}

}

در اين مثال، كلاس InterfaceImplementer همانند ارث‌بري از يك كلاس، از واسط IMyInterface ارث‌بري كرده است. حال كه اين كلاس از واسط مورد نظر ارث‌بري كرده است، بايد، توجه نماييد بايد، تمامي اعضاي آنرا پياده‌سازي كند. در اين مثال اين عمل با پياده‌سازي تنها عضو واسط يعني متد MethodToImplement() انجام گرفته است. توجه نماييد كه پياده‌سازي متد بايد دقيقا از لحاظ نوع بازگشتي و تعداد و نوع پارامترها شبيه به اعلان موجود در واسط باشد، كوچكترين تغييري باعث ايجاد خطاي كامپايلر مي‌شود. مثال زير نحوه ارث‌بري واسطها از يكديگر نيز نمايش داده شده است.

ابتدای صفحهF

 

مثال 2-13 : ارث‌بري واسطها از يكديگر

using System;

interface IParentInterface

{

void ParentInterfaceMethod();

}

 

interface IMyInterface : IParentInterface

{

void MethodToImplement();

}

 

class InterfaceImplementer : IMyInterface

{

static void Main()

{

InterfaceImplementer iImp = new InterfaceImplementer();

iImp.MethodToImplement();

iImp.ParentInterfaceMethod();

} 

public void MethodToImplement()

{

Console.WriteLine("MethodToImplement() called.");

}

public void ParentInterfaceMethod()

{

Console.WriteLine("ParentInterfaceMethod() called.");

}

}

مثال 2-13 داراي 2 واسط است : يكي IMyInterface و واسطي كه از آن ارث مي‌برد يعني IParentInterface. هنگاميكه واسطي از واسط ديگري ارث‌بري مي‌كند، كلاس يا ساختاري كه اين واسطها را پياده‌سازي مي‌كند، بايد تمامي اعضاي واسطهاي موجود در سلسله مراتب ارث‌بري را پياده‌سازي نمايد. در مثال 2-13، چون كلاس InterfaceImplementer از واسط IMyInterface ارث‌بري نموده، پس از واسط IParentInterface نيز ارث‌بري دارد، از اينرو بايد كليه اعضاي اين دو واسط را پياده‌سازي نمايد.

ابتدای صفحهF  

Back Next

  صفحه اصلی
    C# آموزش
    مفاهیم شی گرایی
    برنامه های نمونه
    کار با محیط
    معرفی کتاب
    نقشه سایت
    درباره ما
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
                               
[صفحه اصلی] [آموزش #C] [مفاهیم شی گرایی] [برنامه های نمونه] [کار با محیط] [معرفی کتاب] [نقشه سایت] [درباره ما]