Опубликован: 25.03.2010 | Доступ: свободный | Студентов: 1447 / 158 | Оценка: 4.31 / 4.00 | Длительность: 25:42:00
Лекция 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. Ввожу код на сайте, пишет:

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

 

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