"> Interface ها در سی شارپ 8 | آموزش سی شارپ | ام اس پی سافت

Interface ها در سی شارپ ۸

سی شارپ 8

یک رابط سی شارپ حاوی تعاریف یک کلاس یا ساختاری است که می تواند از طریق کلاس های مشتق شده پیاده سازی شود.

این مقاله به شرح Interface در سی شارپ ۸ می پردازد.

همانطور که همگی می دانیم، سی شارپ ۸ دارای ویژگی های جالب بسیاری می باشد.

همراه با انتشار سی شارپ ۸، تغییرات قابل توجهی در Interface ها اتفاق افتاده است.

موضوعات مورد بحث این مقاله در ادامه آمده است:

  1. Interface ها در دنیای امروز
  2. Modifier ها در Interfaces
  3.  متدهای پیش فرض
  4. Diamond Problem
  5.  نتیجه گیری

Interface ها در دنیای امروز

به عنوان یک توسعه دهنده، همگی از Interface ها بهره می بریم، چه برای ایجاد کامپوننتی با اتصال loosely و چه تعریف قراردادی که باید توسط کلاس عینی پیاده سازی شود.

متدهای Interface امروزه هیچ گاه با بدنه یا تغییر دهنده ها عرضه نمی شوند.

این امر وظیفه ی کلاس پیاده ساز است که بدنه را فراهم کرده و برخی تغییر دهنده ها را به آن تخصیص دهد.

اگر کلاس، متد را پیاده سازی نکند، کامپایلر آن را گرفته و خطایی با این مفهوم که باید Interface را پیاده سازی کنیم می دهد.

یک مثال ساده ی Logger در ادامه آورده شده است.

using System;  
public interface ILogger {  
    void Log(string Info);  
}  
public class TextLogger: ILogger {  
    public void Log(string Info) => Console.Write("In base Logger");  
}  

یک رابط با نام ILogger با یک متد Log() تعریف کرده ایم.

کلاسی به نام TextLogger داریم که رابط ILogger را پیاده سازی می کند. این امر با توجه به وضعیت فعلی طراحی بسیار مناسب است.

حال، مشکل در زمانی رخ میدهد که می خواهیم ILogger را توسعه دهیم و باید اطلاعات بیشتری را بصورت زیر به آن اضافه کنیم.

public interface ILogger {  
    void Log(string info);  
    void Log(string typeofInformation, string info)  
}  

اکنون، مسئله ای در این جا رخ خواهد داد؛ چرا که این متد جدید باید توسط کلاسی که Interface در آن استفاده شده پیاده سازی شود و کامپایلر خطایی را نمایش خواهد داد تا زمانی که این کار بصورت زیر انجام شود.

Interfaces Today

حال، با توجه به اینکه Interface توسط چندین سرویس گیرنده مورد استفاده واقع شده است، موجب تغییرات بسیاری خواهد شد و انجام این تغییرات در سراسر پیاده سازی کاری بسیار دشوار خواهد بود.

بسته به مکان هایی که Interface مورد استفاده قرار گرفته، باید این متد را در سراسر کلاس ها پیاده سازی کنیم تا کد ما کامپایل شود.

جهت غلبه بر این مسئله، سی شارپ ایده ی Default Methods را در Interface ها مطرح کرده است.

متدهای پیش فرض رابط

علت اصلی داشتن این ویژگی در سی شارپ ۸ ، فراهم آوردن پیاده سازی پیش فرض برای متدهای Interface می باشد.

بنابراین چگونه می توانیم این کار را انجام دهیم؟

بیایید مثال زیر را ببینیم.

using System;  
public interface ILogger {  
    void Log(string info);  
    //Default implementation  
    void LogInfo(string typeofInformation, string info) => Console.Write(typeofInformation + " " + info);  
}  
public class TextLogger: ILogger {  
    public void Log(string info) => Console.Write("In base Logger");  
}  

در اینجا، می توانیم در خود Interface مشاهده کنیم که پیاده سازی را برای تابع فراهم کرده ایم.

در اینجا کلاس TextLogger ما نیاز به پیاده سازی این متد نداشته و هیچ خطایی زمان کامپایلی رخ نخواهد داد.

اکنون، به منظور بکارگیری Interface در برنامه ی خود، بیایید متد اصلی خود را تغییر داده و ببینیم که چگونه می توانیم از آن استفاده کنیم.

class Program {  
    static void Main(string[] args) {  
        ILogger _logger = new TextLogger();  
        _logger.LogInfo("Test", "test"); // It will call the Default method of the interface.  
    }  
  }  
}  

یک مورد جالب در Interface ها با متدهای پیش فرض این است که تنها در صورتیکه با کلاس بصورت محتوایی به عنوان یک رابط برخورد شود، کار خواهد کرد.

اگر این کار را انجام ندهیم، آنگاه پیاده سازی متد پیش فرض جهت استفاده در دسترس نخواهد بود.

Modifiers in Interfaces

اگر از نزدیک به این ویژگی نگاه کنیم، می توانیم مشاهده کنیم که می تواند به مسئله ی بسیار معروف و شناخته شده ی Multiple Inheritance  منجر شود که عموما با عنوان Diamond Problem شناخته می شود.

به لحاظ طراحی، سی شارپ با هیچ مشکلی روبرو نخواهد شد، چرا که Multiple Inheritance با وجود کلاس ها ممکن نیست و Interface ها دارای پیاده سازی متدها نمی باشند، اما با وجود متد پیش فرض، این امر تغییر خواهد کرد.

بیایید ببینیم که این امر در سی شارپ ۰.۸ چگونه مدیریت می شود.

Diamond Problem

Diamond Problem یکی از مشکلات بزرگ زبان ها می باشد، چراکه کلاس های سی شارپ از این ویژگی که حاصل ارث بری چندگانه است، پشتیبانی نمی کند، اما Interface ها می توانند این مسئله را مقداری بسط دهند.

بیایید ببینیم که سی شارپ چگونه آن ها را مدیریت می کند. نمودار زیر Diamond Problem را نمایش می دهد:

Diamond Problem

تصویر فوق، Diamond Problem را به خوبی مجسم می کند.

حال بیایید ببینیم که این مسئله چگونه باInterface های پیش فرض رخ می دهد و سی شارپ چگونه آن را مدیریت می کند.

بیایید Interface ها را بصورت زیر طراحی کنیم.

interface First {  
    void WritetoConsole() => Console.Write("In First");  
}  
interface Second: First {  
    void First.WritetoConsole() => Console.Write("In Second");  
}  
interface Third: First {  
    void First.WritetoConsole() => Console.Write("In Third");  
}  
class FinalClass: Second, Third {}  

Interface

پیغام خطا به این صورت خواهد بود،

Interface member ‘First.WritetoConsole()’ does not have a most specific implementation. Neither ‘Second.First.WritetoConsole()’, nor ‘Third.First.WritetoConsole()’ are most specific. (CS8705) [DeaultInterfaceDemo]

به منظور حل این مسئله بطوری که در خود Error شرح داده شده، باید مشخص ترین بازنویسی را در زمان اجرا فراهم کنیم.

تیم طراحی .NET در Interface بطور مشخص به ما توضیح داده اند:

“پیاده سازی کلاس یک عضو رابط ؛همواره باید بر پیاده سازی پیش فرض در یک رابطه، ارجعیت داشته باشد، حتی اگر از یک کلاس پایه ارث بری شده باشد.

پیاده سازی های پیش فرض همواره تنها برای زمانی که کلاس هیچگونه پیاده سازی عضوی ندارد، جایگزین می باشند.”

بیایید ببینیم که چگونه می توان پیاده سازی پیش فرض را فراهم و این مسئله ی Diamond Problem را رفع نمود:

using System;  
interface First {  
    void WritetoConsole() => Console.Write("In First");  
}  
interface Second: First {  
    void First.WritetoConsole() => Console.Write("In Second");  
}  
interface Third: First {  
    void First.WritetoConsole() => Console.Write("In Third");  
}  
class FinalClass: Second, Third {  
    void First.WritetoConsole() {  
        Console.Write("From Final class");  
    }  
} 

Modifierها در رابط ها

بطور سنتی، تا زمان ورود سی شارپ ۸ ، قادر نبودیم از modifier ها در Interface ها استفاده کنیم.

modifier هایی از جمله private، protected، internal، public، و virtual مجاز هستند.

به لحاظ طراحی، تمامی متدهای پیش فرض رابط مجازی سازی شده اند، مگر اینکه خودمان آن ها را private یا sealed کنیم.

تمامی اعضای بدون بدنه، بطور پیش فرض به عنوان انتزاعی در نظر گرفته می شوند، که پیاده سازی در کلاس های عینی را الزامی می کند.

using System;  
interface IInterfaceModifiers {  
    //By Default default method is private  
    virtual void DefaultMethod() => Console.WriteLine("Default method");  
    //Private Default Method  
    private void privatedefaultmethod() => Console.WriteLine(" private Default method");  
    //Protected Default Method  
    protected void ProtectedDefaultMethod() => Console.WriteLine(" protected Default method");  
    // Public Default Method  
    public void PublicDefaultMethod() => Console.WriteLine(" public Default method");  
    virtual void VirtualDefaultMethod() => Console.WriteLine("Virtual Default method");  
    abstract void AbstractDefaultMethod();  
}  
class InterfaceModifierDemo: IInterfaceModifiers {  
    public void AbstractDefaultMethod() => Console.WriteLine("Abstract virtual method");  
}  
namespace DeaultInterfaceDemo {  
    class Program {  
        static void Main(string[] args) {  
            IInterfaceModifiers i = new InterfaceModifierDemo();  
            i.AbstractDefaultMethod();  
            i.DefaultMethod();  
            i.PublicDefaultMethod();  
            i.VirtualDefaultMethod();  
        }  
    }  
}  

هنگامی که کد فوق را اجرا می کنیم، می توانیم خروجی زیر را در کنسول مشاهده کنیم

  •  Abstract virtual method
  •  Default method
  •  public Default method
  • Virtual Default method

هنگامی که یک متد را virtual می کنیم، می توانیم آن متد را درون خود Interface بازنویسی کنیم، و قادر نخواهیم بود آن را در کلاس پیاده سازی بازنویسی کنیم.

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

بطور پیش فرض، اعضای Interface ها abstract هستند، که کلاس پیاده سازی را ملزم به پیاده سازی مناسب آن ها می کند.

خلاصه

بحث انگیزترین و در عین حال هیجان انگیزترین قابلیت سی شارپ ۸ را دیده ایم.

این امر، روشی که از Interface ها در طراحی استفاده میکردیم را تغییر خواهد داد، که قطعا توسعه دهندگان را در ایجاد تغییرات جنجالی کمتر یاری خواهد کرد، اما چالش های خود را در عملکرد و طراحی خواهد داشت.

مورد دیگر اینکه در زمان حال، این قابلیت در .NET Framework موجود نخواهد بود اما در .NET Core و Core CLR و نیز MONO گنجانده شده است.

  • پسورد: www.mspsoft.com
زهره سلطانیان

نوشته‌های مرتبط

دیدگاه‌ها

*
*

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

کدیشن ! مارکت پروژه های برنامه نویسی راه اندازی شدیه توکه پا بریم ببینم