Может ли структура реализовывать интерфейс?

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

Когда один интерфейс наследует другой, то в производном интерфейсе может быть объявлен член, скрывающий член с аналогичным именем в базовом интерфейсе. Такое сокрытие имен происходит в том случае, если член в производном интерфейсе объявляется таким же образом, как и в базовом интерфейсе. Но если не указать в объявлении члена производного интерфейса ключевое слово new, то компилятор выдаст соответствующее предупреждающее сообщение.

Для явной реализации интерфейсного метода могут быть две причины. Во-первых, когда интерфейсный метод реализуется с указанием его полного имени, то такой метод оказывается доступным не посредством объектов класса, реализующего данный интерфейс, а по интерфейсной ссылке. Следовательно, явная реализация позволяет реализовать интерфейсный метод таким образом, чтобы он не стал открытым членом класса, предоставляющего его реализацию. И во-вторых, в одном классе могут быть реализованы два интерфейса с методами, объявленными с одинаковыми именами и сигнатурами. Но неоднозначность в данном случае устраняется благодаря указанию в именах этих методов их соответствующих интерфейсов. Рассмотрим каждую из этих двух возможностей явной реализации на следующем примере:

using System;

namespace ConsoleApplication1
{
    public interface IName
    {
        void WriteName();
    }

    public interface INameFamily
    {
        // Объявляем в данном интерфейсе такой же метод
        void WriteName();
        void WriteFamily();
    }

    public interface IUserInfo : INameFamily
    {
        // Обязательно нужно указать ключевое слово new
        // чтобы не скрывались методы базового интерфейса
        new void WriteName();
        void WriteUserInfo();
    }

    // Класс, реализующий два интерфейса
    class UserInfo : IUserInfo,IName
    {
        string ShortName, Family, Name;

        public UserInfo(string Name, string Family, string ShortName)
        {
            this.Name = Name;
            this.Family = Family;
            this.ShortName = ShortName;
        }

        // Используем явную реализацию интерфейсов
        // для исключения неоднозначности
        void IName.WriteName()
        {
            Console.WriteLine("Короткое имя: " + ShortName);
        }

        void INameFamily.WriteFamily()
        {
            Console.WriteLine("Фамилия: " + Family);
        }

        void INameFamily.WriteName()
        {
            Console.WriteLine("Полное имя: " + Name);
        }

        void IUserInfo.WriteName() { }

        public void WriteUserInfo()
        {
            UserInfo obj = new UserInfo(Name, Family, ShortName);
            // Для использования закрытых методов необходимо
            // создать интерфейсную ссылку
            IName link1 = (IName)obj;
            link1.WriteName();
            INameFamily link2 = (INameFamily)obj;
            link2.WriteName();
            link2.WriteFamily();
            IUserInfo link3 = (IUserInfo)obj;
            link3.WriteName();
        }
    }

    class Program
    {
        static void Main()
        {
            UserInfo obj = new UserInfo(Name: "Alexandr", ShortName: "Alex", Family: "Erohin");
            obj.WriteUserInfo();
            Console.ReadLine();
        }
    }
}
Явная реализация нескольких интерфейсов в C#

Важно уяснить, что интерфейсы являются фундаментальным компонентом .NET Framework. Какого бы типа приложение не разрабатывалось (веб-приложение, приложение с настольным графическим интерфейсом, библиотека доступа к данными и т.п.), работа с интерфейсами будет обязательной частью этого процесса. Подводя итог всему изложенному, отметим, что интерфейсы могут приносить чрезвычайную пользу в следующих случаях:

  • При наличии единой иерархии, в которой только какой-то набор производных типов поддерживает общее поведение.
  • При необходимости моделировать общее поведение, которое должно встречаться в нескольких иерархиях, не имеющих общего родительского класса помимо System.Object.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *