همانطور که در فصول گذشته مشاهده کردید کلاس‌ها و متدها را می‌توان در طی یک برنامه کنترل و محدودیت‌هایی روی آنها اعمال کرد که معمولا به مجموعه‌ی این عملیات Polymorphism گفته می‌شود. اما طی این آموزش‌ها به کلمه‌ی واسط یا Interface‌ زیاد اشاره کردیم. یکی از مهم‌ترین مباحث در زبان برنامه‌نویسی #C رابط‌ها یا واسطه‌ها هستن که در ساختار کدنویسی با نام Interface شناخته می‌شوند. در این فصل مفاهیمی که در این رابطه پوشش خواهیم داد به صورت زیر می‌باشد:

  • معرفی مفهوم واسط‌ها یا Interface ها
  • تعریف یک واسط یا Interface
  • نحوه‌ی استفاده از یک واسط
  • نحوه‌ی پیاده‌سازی ارث‌بری (Inheritance) در واسط‌ها (Interface)

واسط یا Interface چیست؟

واسط‌ها دقیقا مشابه کلاس‌ها بوده با این تفاوت که پیاده‌سازی نمی‌شوند. یعنی کد خاصی برای اجرای آنها ارائه نمی‌گردد. تنها نکته‌ای که وجود دارد: Interface ها شامل تعاریفی مانند events (رویدادها)، indexers (شاخص‌ها)، methods (متدها) و properties (ویژگی‌ها) هستند. علت اینکه واسط‌ها یا Interface کدنویسی نمی‌شود این است که آنها از کلاس‌ها یا ساختارها (struct) ارث‌بری می‌کنند.

حال که یک تعریف کلی از واسط‌ها ارائه دادیم، ممکن است این سوال برای شما پیش بیاید که interface ها چه کاربردی دارند؟ در پاسخ به این سوال باید بگوییم که interface ها قابلیت پیاده‌سازی چندین ویژگی از چندین interface مختلف را در یک کلاس یا struct در اختیار ما می‌گذارند. در ادامه بیشتر آشنا خواهید شد.

تعریف یک واسط یا interface

ساختار کلی تعریف یک واسط به صورت زیر است:

بنابراین در این ساختار داریم:

access-modifier:  جهت تعیین سطح دسترسی می‌باشد.

interface: به عنوان یک کلمه‌ی کلیدی در تعریف واسط بکارگرفته می‌شود.

name: به عنوان نام یک واسط شناخته می‌شود. برای تعریف یک واسط بهتر است از کلمه‌ی I در ابتدای آن استفاده کنید به عنوان مثال IName یا IMessage یا IDatabse

member: مجموعه‌ی متدها و ویژگی‌ها یا در حالت کلی اعضای واسط‌ها در این بخش قرار می‌گیرد. توجه داشته باشید که باید یک تعریف کلی برای هر عضو صورت پذیرد و سطح دسترسی اعضا در حالت عمومی (public) قرار گیرد.

برای تفهیم این موضوع یک مثال ساده می‌زنیم:

همانطور که در مثال فوق مشاهده می‌کنید، سطح دسترسی‌ای برای متد و خصوصیت مشخص نشده است. همچنین متد موجود در interface بدنه ندارد یا به عبارت دیگر فقط حاوی signature است. در ادامه قصد داریم از این واسط استفاده کنیم.

برای استفاده از یک واسط کافیست مانند حالتی که می‌خواهیم یک کلاس فرزند تعریف کرده تا یک سری خصوصیت و متد از کلاس والد به ارث ببرد، عمل کنیم بنابراین داریم:

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

اما برای استفاده از یک واسط چگونه باید عمل کرد؟ اگر یادتان باشد در محبث مربوط به ارث‌بری مطرح کردیم که اگر کلاس فرزند از کلاس وارث مشتق شود آنگاه تمام خصوصیات و ویژگی‌ها و متدهای موجود در کلاس والد را در اختیار دارد. این موضوع برای واسط‌ها نیز صادق است. در حقیقت می‌توان از واسط‌ها برای ایجاد شیء استفاده کرد: