Опубликован: 25.03.2010 | Уровень: для всех | Доступ: платный
Лекция 10:

Интерфейсы, делегаты, события в C#

Диаграмма UML для приведенного кода, построенная в Visual Studio 2005, выглядит следующим образом


Реализующий класс явно адресует унаследованный от интерфейса метод. Синтаксис допускается только закрытое по умолчанию объявление реализации метода (без применения любых модификаторов доступа), чтобы наверняка исключить неопределенность во внешнем по отношению к реализующему классу коде. Для возможности вызова реализации метода из внешнего кода применяют дополнительные public -функции доступа, из которых вызывают private -реализацию. Они повторяют имена интерфейсных функций или могут иметь любые другие имена, но в последнем случае идея интерфейсов теряет смысл.

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

Если члены интерфейсов имеют не только одинаковое имя, но и одинаковую сигнатуру, и хотя бы один из них реализован, то оставшиеся члены нейтрализовывать необязатально.

Если наследуемые интерфейсы имеют абсолютно одинаковые члены (имя и сигнатура), то их можно рассматривать как одинаковые инструкции, реализовать только один член, а остальные скрывать не необязательно. Это ведь одинаковый шаблон. Но все различающиеся ненужные члены надо скрывать пустой закрытой реализацией.

using System;
    
namespace Test
{
    interface A
    {
        void Show();
        void Foo();
    }
    
    interface B
    {
        void Show();
        int Foo(string str);
    }
    
    // Обязаны реализовать все, но все клиенту не нужно 
    class C : A, B
    {
        // Реализуем то, что нужно клиенту 
        void A.Show()
        {
            Console.WriteLine("Реализация A.Show()");
        }
    
        public void Show()
        {
            ((A)this).Show();
        }
    
        int B.Foo(string str)
        {
            Console.WriteLine("Реализация B.Foo()");
            return 0;
        }
        public int Foo(string str)
        {
            return ((B)this).Foo(str);
        }
    
        // Нейтрализуем все остальное, что клиенту не нужно 
        void A.Foo() { }
    }
    
    // Вызывающий код
    class Program
    {
        static void Main()
        {
            // Настройка консоли
            Console.Title = "Применение интерфейсов";
            Console.ForegroundColor = ConsoleColor.White;
            Console.CursorVisible = false;
            Console.WindowWidth = 30;
            Console.WindowHeight = 3;
    
            C obj = new C();
            obj.Show();
            obj.Foo(String.Empty);
    
            Console.ReadLine();
        }
    }
}
Листинг 10.4 . Выборочная реализация членов интерфейса

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

Диаграмма UML данного примера будет такой


Результат выполнения


Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.

 

Как активировать код?

Денис Пашков
Денис Пашков
Россия
Татьяна Ковалюк
Татьяна Ковалюк
Украина, Киев, Киевский политехнический институт, 1974