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

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

Реализация методов интерфейса как виртуальных
using System;
    
namespace Test
{
    // Объявление интерфейса
    interface IDraw
    {
        void Show();
    }
    
    // Реализуем интерфейсный метод как виртуальный
    class A : IDraw
    {
        string name = "Класс A";
        public virtual void Show()
        {
            Console.WriteLine("\t" + name);
        }
    }
    
    // Переопределяет унаследованный виртуальный метод
    class B : A
    {
        string name = "Класс B";
        public override void Show()
        {
            Console.WriteLine("\t" + name);
        }
    }
    
    // Вызывающая сторона
    class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("Адресация ссылками типов объектов:");
            A a = new A(); a.Show();
            B b = new B(); b.Show();
    
            Console.WriteLine("\nАдресация ссылкой 
              типа унаследованного интерфейса\n"
                + "(динамический полиморфизм):");
            IDraw refInterface = new A(); refInterface.Show();
            refInterface = new B(); refInterface.Show();
        }
    }
    
    // Запуск
    class Program
    {
        static void Main()
        {
            // Настройка консоли
            Console.Title = "Производить объекты 
              абстрактных классов запрещено";
            Console.ForegroundColor = ConsoleColor.White;
            Console.CursorVisible = false;
            Console.WindowWidth = 60;
            Console.WindowHeight = 10;
    
            new MyClass();// Чтобы сработал конструктор
    
            Console.ReadLine();
        }
    }
}
Применение библиотечных интерфейсов

В библиотеке .NET Framework объявлено множество интерфейсов, применение некоторых из них мы здесь проиллюстрируем.

Создание индексаторов и нумераторов

Пусть некоторый класс содержит коллекцию однотипных элементов, которые нужно перебрать с помощью цикла foreach. Такие коллекции называются нумераторами. В этом случае класс должен реализовать интерфейсы System.Collections.IEnumerable и System .Collections.IEnumerator, расположенные в сборке mscorlib.

В интерфейсе IEnumerable объявлен единственный метод

IEnumerator GetEnumerator()

который возвращает ссылку на сам объект коллекции. Его в реализующем классе нужно определять так

public IEnumerator GetEnumerator()
  { 
           // Приводим ссылку на объект к интерфейсному типу
            // и возвращаем адрес экземпляра класса
            return (IEnumerator)this;
        }
Листинг 10.5 . Определение члена интерфейса IEnumerable в реализующем классе

Интерфейс IEnumerator содержит одно свойство и два метода, приведенные в таблице

Таблица 10.1 . Члены библиотечного интерфейса IEnumerator
Член Пояснения
public object Current { get; } Возвращает текущий элемент в коллекции
bool MoveNext() Переводит внутренний указатель к следующему элементу коллекции. Если коллекция исчерпана, то возвращается false
void Reset() Устанавливает указатель перед первым элементом коллекции
Создание индексаторов

Пусть мы создали пользовательский класс Person с данными сотрудника и класс Persons, который будет содержать массив объектов класса Person с данными сотрудников. Для того, чтобы можно было обращаться в классе Persons к отдельным объектам-элементам массива, характеризующим отдельных сотрудников, нужно в нем предусмотреть индексатор. Обрабатывать отдельных сотрудников внутри класса Persons можно только как элементы массива. Вот код этого примера

using System;
    
namespace Test
{
    class Person
    {
        // Закрытые поля с данными сотрудника
        string name;    // Имя
        int age;        // Возраст
    
        // Конструктор по умолчанию
        public Person()
        {
            name = "Петров";
            age = 21;
        }
    
        // Конструктор с параметрами
        public Person(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
    
        // Свойства чтения/записи
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
    }
    
    class Persons
    {
        // Объявляем закрытую ссылку-поле на массив сотрудников
        private Person[] personArray;
    
        // Конструктор
        public Persons()
        {
            personArray = new Person[]{
                new Person("Иванов",20),
                new Person(),// По умолчанию Person("Петров", 21)
                new Person("Сидоров", 22)
            };
        }
    
        // Свойство-индексатор
        public Person this[int index]
        {
            get
            {
                if (index < 0)
                    return personArray[0];
                else if (index > personArray.Length - 1)
                    return personArray[personArray.Length - 1];
                else
                    return personArray[index];
            }
            set
            {
                if (index < 0)
                    personArray[0] = value;
                else if (index > personArray.Length - 1)
                    personArray[personArray.Length - 1] = value;
                else
                    personArray[index] = value;
            }
        }
    
        // Количество сотрудников
        public int Length
        {
            get { return personArray.Length; }
        }
    }
    
    // Вызывающая сторона
    class MyClass
    {
        public MyClass()
        {
            // Создаем список сотрудников
            Persons pers = new Persons();
            // Выводим информацию о сотрудниках по индексатору
            Console.WriteLine("Список сотрудников:");
            for (int i = 0; i < pers.Length; i++)
                Console.WriteLine("{2}) {0}, возраст {1}",
                    pers[i].Name, pers[i].Age, i + 1);
    
            /* Нужно реализовать интерфейсы IEnumerable, IEnumerator
            Console.WriteLine("\nЕще один список сотрудников:");
            int j = 0;
            foreach (Person per in pers)
                Console.WriteLine("{2}) {0}, возраст {1}",
                    per.Name, per.Age, j = j + 1);
            //*/
        }
    }
    
    // Запуск
    class Program
    {
        static void Main()
        {
            // Настройка консоли
            Console.Title = "Применение индексаторов";
            Console.ForegroundColor = ConsoleColor.White;
            Console.CursorVisible = false;
            Console.WindowWidth = 30;
            Console.WindowHeight = 10;
    
            new MyClass();// Чтобы сработал конструктор
    
            Console.ReadLine();
        }
    }
}
Листинг 10.6 . Класс Persons как индексный массив объектов Person

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

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

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

 

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

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