Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الواجهات المتعددة

جزء من قسم 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. تمثل كل واجهة قدرة واحدة، ويمكن لفئتك المزج والمطابقة بين ما تحتاجه بالضبط.

challenge icon

التحدي

سهل

لنقم ببناء نظام أجهزة منزلية ذكية يوضح كيف يمكن لفئة واحدة تنفيذ واجهات متعددة لاكتساب قدرات مختلفة. ستقوم بإنشاء أجهزة يمكن التحكم فيها ولديها ميزات إدارة الطاقة في آن واحد.

ستقوم بتنظيم الكود الخاص بك عبر أربعة ملفات:

  • 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)
        
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming