Menu
Coddy logo textTech

Множественные интерфейсы

Часть раздела Объектно-ориентированное программирование путешествия по 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. Каждый интерфейс представляет собой отдельную возможность, и ваш класс может комбинировать именно то, что ему нужно.

challenge icon

Задание

Легко

Давайте создадим систему устройств для умного дома, которая демонстрирует, как один класс может реализовывать несколько интерфейсов для получения различных возможностей. Вы создадите устройства, которые могут быть как управляемыми, так и иметь функции сетевого подключения.

Вы организуете свой код в четырех файлах:

  • IControllable.cs: Определите интерфейс с именем IControllable в пространстве имен SmartHome. Этот интерфейс представляет устройства, которые можно включать и выключать. Он должен объявлять два метода: TurnOn() и TurnOff(), оба возвращающие строку.
  • INetworkConnected.cs: Определите интерфейс с именем INetworkConnected в пространстве имен SmartHome. Этот интерфейс представляет устройства, которые могут подключаться к сети. Он должен объявлять метод Connect(string network), который возвращает строку.
  • SmartTV.cs: Определите класс SmartTV в пространстве имен SmartHome, который реализует как IControllable, так и INetworkConnected. У телевизора должно быть свойство Brand (string) и свойство ScreenSize (int, представляющее дюймы). Создайте конструктор, принимающий оба значения. Реализуйте все методы интерфейса:
    • 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: Сохраните один и тот же объект TV в переменных трех разных типов:
        // 1. Тип SmartTV (конкретный класс)
        // 2. Тип IControllable (ссылка на интерфейс)
        // 3. Тип INetworkConnected (ссылка на интерфейс)
        
        // TODO: Выведите результат в требуемом формате:
        // Через SmartTV:
        // - Вызовите TurnOn() и Connect(network)
        // Через IControllable:
        // - Вызовите TurnOff()
        // Через INetworkConnected:
        // - Вызовите Connect(network)
        
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование