الواجهات المتعددة
جزء من قسم البرمجة كائنية التوجه في رحلة C# على Coddy. الدرس 27 من 70.
بينما يمكن للفئة أن ترث من فئة أساسية واحدة فقط، يمكنها تنفيذ أي عدد من الواجهات حسب الحاجة. وهذه إحدى المزايا الرئيسية التي تتمتع بها الواجهات مقارنةً بالفئات المجرّدة؛ إذ تتيح للفئة اعتماد سلوكيات متعددة.
لتنفيذ عدة واجهات، ما عليك سوى إدراجها بعد النقطتين، مع فصلها بفواصل:
public interface IFlyable
{
void Fly();
}
public interface ISwimmable
{
void Swim();
}
public class Duck : IFlyable, ISwimmable
{
public void Fly()
{
Console.WriteLine("Flying through the air");
}
public void Swim()
{
Console.WriteLine("Swimming in the pond");
}
}يجب أن تنفّذ الفئة Duck جميع الأعضاء من كلتا الواجهتين. يحاكي هذا سيناريوهات العالم الحقيقي بشكل طبيعي - فالبطة تستطيع فعليًا الطيران والسباحة معًا، لذا من المنطقي أن تفي بكلا العقدين.
عند الجمع بين الوراثة والواجهات المتعددة، يجب أن تأتي الفئة الأساسية أولًا:
public class Duck : Bird, IFlyable, ISwimmable
{
// يرث من Bird، وينفذ كلا الواجهتين
}تتيح لك هذه المرونة تركيب السلوكيات من مصادر متعددة. قد تطبّق Robot الواجهات IMovable وIChargeable وISpeakable. تمثّل كل واجهة قدرة واحدة، ويمكن لفئتك المزج والمواءمة بدقة لما تحتاج إليه.
التحدي
سهللنَبْنِ نظامًا لأجهزة المنزل الذكي يوضّح كيف يمكن لفئة واحدة أن تنفّذ عدة interfaces لاكتساب إمكانات مختلفة. ستنشئ أجهزة يمكن التحكم فيها، وتحتوي أيضًا على ميزات لإدارة الطاقة.
ستنظّم شيفرتك عبر أربعة ملفات:
IControllable.cs: عرّفinterfaceباسمIControllableفي مساحة الأسماءSmartHome. يمثّل هذاinterfaceالأجهزة التي يمكن تشغيلها وإيقاف تشغيلها. ويجب أن يعلن عنmethodsاثنتين:TurnOn()وTurnOff()، وكلتاهما تعيدان قيمة من النوع string.INetworkConnected.cs: عرّفinterfaceباسمINetworkConnectedفي مساحة الأسماءSmartHome. يمثّل هذاinterfaceالأجهزة التي يمكنها الاتصال بشبكة. ويجب أن يعلن عنmethodباسمConnect(string network)يعيد قيمة من النوع string.SmartTV.cs: عرّفclassباسمSmartTVفي مساحة الأسماءSmartHome، بحيث تنفّذ كلًا منIControllableوINetworkConnected. يجب أن يحتوي التلفاز على خاصيةBrandمن النوع string، وخاصيةScreenSizeمن النوع int، التي تمثّل المقاس بالبوصة. أنشئConstructorيقبل القيمتين كلتيهما. نفّذ جميعmethodsالخاصة بـinterfaces:TurnOn()تعيد"{Brand} {ScreenSize}-inch TV is now ON"TurnOff()تعيد"{Brand} {ScreenSize}-inch TV is now OFF"Connect(string network)تعيد"{Brand} TV connected to {network}"
Program.cs: في ملفك الرئيسي، أنشئSmartTVباستخدام قيم الإدخال. وضّح مرونةinterfacesالمتعددة من خلال تخزين كائن التلفاز نفسه في ثلاثة أنواع مختلفة من المتغيرات: النوعSmartTVالملموس، ومتغير من النوعIControllable، ومتغير من النوعINetworkConnected. استدعِmethodsالمناسبة عبر كل مرجع، لإظهار كيف يمكن التعامل مع الكائن نفسه بطرق مختلفة اعتمادًا علىinterfaceالذي تعمل معه.
ستتلقى ثلاثة مدخلات:
- اسم علامة التلفاز التجارية
- مقاس الشاشة بالبوصة
- اسم الشبكة المراد الاتصال بها
اطبع الناتج بهذا التنسيق:
Via SmartTV:
{TurnOn() result}
{Connect(network) result}
Via IControllable:
{TurnOff() result}
Via INetworkConnected:
{Connect(network) result}على سبيل المثال، إذا كانت المدخلات هي Samsung و55 وHomeWiFi، فيجب أن يكون الناتج:
Via SmartTV:
Samsung 55-inch TV is now ON
Samsung TV connected to HomeWiFi
Via IControllable:
Samsung 55-inch TV is now OFF
Via INetworkConnected:
Samsung TV connected to HomeWiFiلاحظ كيف يمكن الوصول إلى كائن SmartTV نفسه عبر مراجع مختلفة لـinterfaces. عند تخزينه باعتباره IControllable، يمكنك فقط استدعاء methods التحكم. وعند تخزينه باعتباره INetworkConnected، يمكنك فقط استدعاء methods الشبكة. هذه هي قوة تنفيذ interfaces متعددة — إذ تكتسب class واحدة إمكانات متعددة، مع الحفاظ على المرونة في طريقة استخدامها!
جرّب بنفسك
using System;
using SmartHome;
class Program
{
public static void Main(string[] args)
{
// اقرأ المدخلات
string brand = Console.ReadLine();
int screenSize = Convert.ToInt32(Console.ReadLine());
string network = Console.ReadLine();
// TODO: أنشئ كائن SmartTV بالقيم المدخلة
// TODO: خزّن نفس كائن التلفزيون في ثلاثة أنواع متغيرات مختلفة:
// 1. نوع SmartTV (فئة ملموسة)
// 2. IControllable type (interface reference)
// 3. INetworkConnected type (interface reference)
// TODO: اطبع المخرجات بالتنسيق المطلوب:
// Via SmartTV:
// - استدعِ TurnOn() و Connect(network)
// Via IControllable:
// - استدعِ TurnOff()
// Via INetworkConnected:
// - استدعِ Connect(network)
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injectionتدرّب بنفسك: مترجم C# عبر الإنترنت