الواجهات المتعددة
جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 27 من 70.
بينما يمكن للفئة (class) أن ترث من فئة أساسية (base class) واحدة فقط، إلا أنها تستطيع تنفيذ أي عدد من الواجهات (interfaces) حسب الحاجة. هذه إحدى المزايا الرئيسية للواجهات مقارنة بالفئات المجردة (abstract classes) - فهي تسمح للفئة بتبني سلوكيات متعددة.
لتنفيذ واجهات متعددة، ما عليك سوى إدراجها بعد النقطتين الرأسيتين، مفصولة بفاصلة:
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. تمثل كل واجهة قدرة واحدة، ويمكن لفئتك المزج والمطابقة بين ما تحتاجه بالضبط.
التحدي
سهللنقم ببناء نظام أجهزة منزلية ذكية يوضح كيف يمكن لفئة واحدة تنفيذ واجهات متعددة لاكتساب قدرات مختلفة. ستقوم بإنشاء أجهزة يمكن التحكم فيها ولديها ميزات إدارة الطاقة في آن واحد.
ستقوم بتنظيم الكود الخاص بك عبر أربعة ملفات:
IControllable.cs: قم بتعريف واجهة تسمىIControllableداخل مساحة الأسماءSmartHome. تمثل هذه الواجهة الأجهزة التي يمكن تشغيلها وإيقاف تشغيلها. يجب أن تعلن عن طريقتين:TurnOn()وTurnOff()، وكلاهما يعيد سلسلة نصية (string).INetworkConnected.cs: قم بتعريف واجهة تسمىINetworkConnectedداخل مساحة الأسماءSmartHome. تمثل هذه الواجهة الأجهزة التي يمكنها الاتصال بشبكة. يجب أن تعلن عن طريقةConnect(string network)تعيد سلسلة نصية.SmartTV.cs: قم بتعريف فئةSmartTVداخل مساحة الأسماءSmartHomeتقوم بتنفيذ كل منIControllableوINetworkConnected. يجب أن يحتوي التلفزيون على خاصيةBrand(string) وخاصيةScreenSize(int، تمثل البوصات). قم بإنشاء منشئ (constructor) يقبل كلتا القيمتين. قم بتنفيذ جميع طرق الواجهة: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باستخدام قيم الإدخال. أظهر مرونة الواجهات المتعددة عن طريق تخزين نفس كائن التلفزيون في ثلاثة أنواع مختلفة من المتغيرات: النوع الملموسSmartTV، ومتغيرIControllable، ومتغيرINetworkConnected. استدعِ الطرق المناسبة من خلال كل مرجع لتوضيح كيف يمكن التعامل مع نفس الكائن بشكل مختلف بناءً على الواجهة التي تعمل معها.
ستتلقى ثلاثة مدخلات:
- اسم العلامة التجارية للتلفزيون
- حجم الشاشة بالبوصة
- اسم الشبكة للاتصال بها
اطبع المخرجات بهذا التنسيق:
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 من خلال مراجع واجهات مختلفة. عند تخزينه كـ IControllable، يمكنك فقط استدعاء طرق التحكم. وعند تخزينه كـ INetworkConnected، يمكنك فقط استدعاء طرق الشبكة. هذه هي قوة تنفيذ واجهات متعددة - تكتسب فئة واحدة قدرات متعددة مع بقائها مرنة في كيفية استخدامها!
ورقة مرجعية
يمكن للفئة تنفيذ واجهات متعددة عن طريق سردها بعد النقطتين الرأسيتين، مفصولة بفاصلة:
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");
}
}يجب أن تقوم الفئة بتنفيذ جميع الأعضاء من كافة الواجهات.
عند الجمع بين الوراثة وواجهات متعددة، يجب أن تأتي الفئة الأساسية أولاً:
public class Duck : Bird, IFlyable, ISwimmable
{
// Inherits from Bird, implements both interfaces
}يسمح هذا بتكوين سلوكيات من مصادر متعددة، حيث تمثل كل واجهة قدرة واحدة.
جرّب بنفسك
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 (فئة ملموسة - concrete class)
// 2. نوع IControllable (مرجع واجهة - interface reference)
// 3. نوع INetworkConnected (مرجع واجهة - interface reference)
// TODO: طباعة المخرجات بالتنسيق المطلوب:
// عبر SmartTV:
// - استدعاء TurnOn() و Connect(network)
// عبر IControllable:
// - استدعاء TurnOff()
// عبر INetworkConnected:
// - استدعاء Connect(network)
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
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