مثالی از اینترفیس در سی شارپ
سه شنبه 19 بهمن 1395در این مقاله توضیحاتی در رابطه با اینترفیس ها در محیط برنامه نویسی سی شارپ به همراه مثال های متعدد بیان شده است.اینترفیس ها در سی شارپ برای پیاده سازی ارث بری چندگانه معرفی شده اند، که با کلاس ها امکان پذیر نیست. با استفاده از اینترفیس ها ما می توانیم دو یا چند اینترفیس را در یک کلاس پیاده سازی کنیم که تعدادی مثال از اینترفیس ها را به شما نشان خواهیم داد.
کلمه قرارداد( contract ) در اینجا برای کلاس مشتق شده به پیاده سازی تمام توابع اجرایی توسط اینترفیس ها الزامی می باشد.
مثالی از اینترفیس ها درسی شارپ
اینترفیس یک گروه منطقی،شامل تعدادی از مجموعه متدهای امضا شده مطلوب می باشد که به مابرای رسیدن به برخی از قابلیت ها کمک میکنند.از آنجا که مجموعه متدهاست خود شامل رویدادها(Events) و همچنین ویژگی ها (Properties) ها میباشند پس می تواند شامل اینترفیس ها نیز باشند. اما اینترفیس ها رانمی توان با متد های سازنده تعریف کرد و نه میتوان آنها را با نمونه ای از شی تعریف کرد و همچنین نمیتوان انها را به عنوان عضو استاتیک تعریف نمود. اینترفیس ها نسخه های وراثت چندگانه را کاهش میدهند. من قبلا نسخه های کاهش مانند کلاس اجرایی در اینترفیس ها را متذکر شده ام که به اجرای تمام متدهای اعلام شده در کلاس های مشتق شده نیاز می باشد. یکی از ویژگی های اصلی اینترفیس این است که اجازه می دهد تا نمونه از انواع مشتق شده در هر جا یک اینترفیس مورد استفاده قرار گیرند ، به درک چرا ازاینترفیس ها استفاده می شود مفید خواهد بود. در نیاز به تعریف یک اینترفیس ما ازکلمه کلیدی Interface استفاده میکنیم و در نمونه متدهای امضا شده قرار میگیرد.
public interface IEmployee { string DoWork(); }
کد بالا را شامل یک متد امضا به نام ()DoWork می باشد .
قبل از اینکه جلو بریم می خواهیم بر چگونه عمل کردن رفتارهای CLR در اینترفیس تاکید کنیم. تعریف اینترفیس CLR درست مثل تعریف یک کلاس می ماند. این کلمات را می توان با یک بازتاب واقعی است تایید کرد : یک کوئری(Query) با ویژگی از نوع اینترفیس ، در کد زیر نشان داده شده است
MethodInfo[] methodInfos = Type.GetType("InterfacesInCSharp.IEmployee").GetMethods(BindingFlags.Public | BindingFlags.Instance);
توابع اینترفیس لزوما باید به صورت عمومی در اجرای کلاس مشتق شده تعریف شوند این یک شرط از سمت کامپایلر سی شارپ می باشد.
پیاده سازی اینترفیس
قبلا یک اینترفیس IEmployee در کد بالا تعریف شده است. حالا می خواهیم اینترفیس را برای کلاس Engineer به صورت زیر پیاده سازی کنم.
public class Engineer:IEmployee { }
حال اگر کد بالا اجرا کنیم یک خطا در زمان کامپایل میدهد
"InterfacesInCSharp.Engineer"که اعضای اینترفیس قابل پیاده سازی نیستند.
"nterfacesInCSharp.IEmployee.DoWork()" :این واضح که CLRانتظار داره که همه توابع در کلاس اجرایی تعریف شوند.
کد صحیح و درست کد بالا در زیر نمایش داده شده است.
public class Engineer:IEmployee { #region IEmployee Members public string DoWork() { return string.Empty; //Function definition } #endregion }
همانطور که از کد بالا مشخص است امضای متد() DoWork در کلاس Engineer همانند امضای متد در اینترفیس IEmployee می باشد.
درست مثل نوع ها، اینترفیس ها را می توان در حوزه فایل تعریف کرد و یا می توان با یک نوع تو در تو به شرح زیر یا در حوزه فایل نشان داد.
public class Engineer : IEmployee { public string DoWork() { return string.Empty; } public interface IMyWork { } }
اینترفیس ها تنها میتوانند از هم نوع خودشان یعنی اینترفیس ها ارث بری کنند
فرض کنید ما می خواهیم اجرای یک اینترفیس در بخش هایی از پروژه بدون ایجاد اختلال در اینترفیس دیگر، گسترش دهیم. ما می توانیم یک اینترفیس جدید ایجاد کنیم و آن را از اینترفیس جدید ارث بری کنیم
public interface IHuman { void SocialAnimal(); } public interface IEmployee : IHuman { string DoWork(); } public class Engineer : IEmployee { public string DoWork() { return string.Empty; } public void SocialAnimal() { //performs social work } }
ایجاد یک متغیر برای نوع اینترفیس
به محض این که اینترفیس ها را ایجاد و اجرا کردیم ، به ایجاد متغیرها نیاز داریم،بنابراین کلاس های پیاده سازی برای دستیابی به عملکرد مطلوب، مدنظر می باشد. ما همیشه می توانیم متغیری از نوع کلاس های پیاده سازی داشته باشیم که در کد زیر انجام شده است.
static void Main(string[] args) { Engineer eng = new Engineer(); }
اما همیشه پیشنهاد میشود که برای ایجاد متغیر از نوع اینترفیس حاوی رفرنس، از کلاس های پیاده سازی استقاده شوند.
static void Main(string[] args) { IEmployee eng = new Engineer(); }
و این مفهوم جدید را می توان با داشتن یک طراحیloosely در نرم افزار پیاده سازی کرد. حالا فرض کنید در این مورد میخواهیم یک تابع ایجاد کنیم که با پارامتر ورودی از نوع IEmployee باشد و از نوع Enginee
public void DoWork(IEmployee emp) { emp.DoWork(); }
انواع مقادیر در پیاده سازی اینترفیس
همانطور که قبلا بحث شد، نوع های مرجع و یا کلاس ها تنها نوع هایی نیستند که به وسیله اینترفیس پیاده سازی میشوند.انواع مقادیر همچنین می تواند با صفر یا چند اینترفیس پیاده سازی شوند. نمونه ها در قطعه کد زیر نشان داده شده :
public struct Employee : IEmployee { public string DoWork() { return string.Empty;//implementation } }
در کد بالا یک استرکت Employee تعریف کرده ایم که از اینترفیس IEmployee که در کد پیاده سازی کرده ایم ارث بری میکند.
هنگامی که ما یک متغیر اینترفیس حاوی رفرنس از انواع مقادیر ایجاد میکنیم، CLR نوع متغیر نمونه را بخش بندی میکند که به عنوان متغیر اینترفیس اشاره به یک نقطه از پشته دارد ، CLR میتوانند نوع اشاره گرهای شی را برای تعیین دقیق شی ها به انواعی که قابل پشتیبانی نیستند بررسی کند. هر زمانی که متغیر اینترفیس برای صدا زدن انواع مختلف متداستفاده شود ،اشاره گر نوع بسته بندی شی ،توسط CLR به دنبال پیدا کردن جدول متد نوع شی به منظور پاسخ مناسب به متد میباشد .
متدهای اینترفیس مجازی هستند!
بله، شما درست خواندید؛ متدهای اینترفیس به صورت مجازی و مهر و موم (sealed) توسط کامپایلر سی شارپ تعریف میشوند. این چیزی که می توان با وارد شدن به کد IL اینترفیس با استفاده از فایل ILDASM.exe بررسی شود. از آنجا که متدهای مانند Salead توسط کامپایلر مشخص شده هستند ما نمی توانیم متدها را در کلاس ها سربارگذاری کنیم.
اما اگر شما می خواهید متد در برخی از کلاس مشتق شده سربار گذاری کنید باید متدها را به عنوان مجازی به صراحت مشخص کنید
به عنوان مثال در کد زیر نشان داده شده است.
public class Engineer : IEmployee { public virtual string DoWork() { return string.Empty; } }
و یک کلاس ارث بردن از کلاس Engineer
public class JuniorEngineer:Engineer { public override string DoWork() { return string.Empty; // return junior engineer's work } }
اجرای صریح و روشن از اینترفیس
فرض کنید دو اینترفیس حاوی متد امضا یکسان وجود دارد، کد زیر این مثال را نمایش میدهد.
interface Interface1 { void DoSomething(); } interface Interface2 { void DoSomething(); }
یک سناریو داریم که در آن به پیاده سازی دوتا اینترفیس با یک کلاس یکسان پرداختیم مثال به شرح زیر برای اینترفیس نشان داده شده است:
public class ExplicitImplentation : Interface1, Interface2 { void Interface1.DoSomething() { } void Interface2.DoSomething() { } }
اجرای صریح هر دو توابع به صورت خصوصی می باشد و می تواند توسط مرجع از کلاس به اینترفیس خاص مورد دستیابی قرار گیرند .
ExplicitImplentation exp = new ExplicitImplentation(); Interface1 int1 = exp; int1.DoSomething(); //prints "i am called from Interface1" Interface2 int2 = exp; int2 = exp; int2.DoSomething(); // prints "i am called from Interface2"
امیدواریم که شما خواندن این مقاله لذت برده باشید و چیزی جدید در این مقاله آموخته باشید و این مقاله را با دوستان خود به اشتراک بگذارید.
- C#.net
- 7k بازدید
- 12 تشکر