Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ЛИПО .doc
Скачиваний:
0
Добавлен:
06.12.2018
Размер:
441.86 Кб
Скачать

Индексаторы

Индексаторы предоставляют возможность доступа к коллекции данных (например, массиву), хранящейся внутри объекта, по такому принципу, как если бы этот объект сам был массивом. Таким образом, вместо применения метода для доступа к данным внут­ри индексаторы позволяют использовать для обычные квадратные скобки аналогично массивам.

Как было показано ранее, массив поддерживает множество полезных встроенных ме­тодов и свойств, например Sort и Length. Однако иногда требуются и дополнительные средства, не предоставляемые классом Array. Может понадобиться массив, способный вычислять сумму и среднее своих элементов или отображать значения четных и нечетных элементов массива. Для этого можно создать класс, подобный мас­сиву с дополнительными возможностями (фактически он будет содержать массив или другую коллекцию как переменную экземпляра).

Напомним, что для обращения к отдельному элементу массива применяется индекс в квадратных скобках после имени:...accounts[4]...

Если объект представляет собой массив, было бы удобно обращаться к его элемен­там так же (по индексу в скобках). Дня этого в С# введен специальный элемент языка — индексатор.

:

Индексаторы позволяют использовать наглядный синтаксис доступа к элементам коллек­ции, инкапсулированной в объекте. Синтаксис состоит из квадратных скобок, внутри ко­торых находится аргумент-индекс, следующий за именем объекта:...myArrayObject[4]...

Концепция индексаторов сходна с концепцией свойств. Свойство имитирует поле, но на самом деле исполняет блоки get и set, а индексатор имитирует массив, но также исполня­ет блоки get и set. В обеих конструкциях применяется идентичный синтаксис.

Несмотря на сходство индексаторов и свойств, между ними имеется и несколько су­щественных различий.

  1. Индексатор нельзя объявить как static. Он должен быть элементом экземпляра, т. е. с помощью квадратных скобок можно обращаться к объектам, но не к клас­сам.

  2. Индексатор идентифицируется объектом, в котором он находится, и комбинаци­ей аргументов в квадратных скобках. Следовательно, у самого индексатора име­ни нет. Поскольку объект трактуется как массив, а индексатор остается аноним­ным, в объявлении его всегда применяется ключевое слово this.

  3. Заголовок объявления индексатора должен включать непустой список формаль­ных параметров.

Рассмотрим синтаксический блок индексатора:

Объявление_свойства::=

[<Спецификатор_доступности>]<Тип> this [Список_ формальных_параметров]

{

[<блок_get>]

[<блок_set>]

}

где

<Спецификатор_доступности>:

::= public

::= private

::= protected

::= internal

::= protected internal

<блок_get>:

::= get

{

[<Операторы>]

return <Выражение>

}

<блок_set>:

::= set

{

[<Операторы> с использованием ключевого слова value]

}

Например, напишем программу, которая при помощи индексатора имитирует массив и в том же классе имеет метод, который выводит сумму элементов массива.

class Mass

{

int[] my_mass;

public Mass(int razm)

{

my_mass = new int [razm];

}

public int this[int index]

{

get

{

return my_mass[index];

}

set

{

my_mass[index] = value;

}

}

public int sum()

{

int sum = 0;

for (int i = 0; i < my_mass.Length; i++)

{

sum = sum + my_mass[i];

}

return sum;

}

}

class Program

{

static void Main(string[] args)

{

Mass myMass = new Mass(5);

for (int i = 0; i < 5; i++)

{

Console.WriteLine("Введите элемент: {0}", i);

myMass[i] = Convert.ToInt32(Console.ReadLine());

}

for (int j = 0; j < 5; j++)

{

Console.WriteLine("Элемент массива с индексом {0} равен: {1}", j, myMass[j]);

}

Console.WriteLine(myMass.sum());

Console.ReadLine();

}

}

Стоит отметить несколько особенностей индексаторов.

  1. В список формальных параметров могут входить формальные параметры любого типа, например типа String Соответствующий аргумент-индекс также будет принадлежать типу string. Такое свой­ство отличается от обычного массива, где применим только индекс, принадлежа­щий одному из типов: uint, int, ulong, long (или неявно преобразуемый в них).

  2. Хотя объект с индексатором имитирует массив (с точки зрения пользователя объекта), его реализация в классе зависит от разработчика.

  3. Хотя доступ к объекту осуществляется теми же средствами, что и к массиву, индексатор не поддерживает методы и свойства обычного массива.

Операции. Перегрузка операций

Перегрузка операций дает возможность применять "+" и "-" для пользовательских ти­пов, избегая громоздких вызовов методов.

События

Наследование

Основы наследования

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

  1. Добавив новые элементы (функции и данные) к производному классу.

  2. Изменив поведение унаследованных функций за счет их новых реализаций.

Понятие наследования является основой еще одной важной концепции ООП — по­лиморфизма. Полиморфизм обеспечивает доступ к объектам разных типов с помощью одной пе­ременной. Это позволяет одному имени функции соответствовать нескольким различ­ным реализациям на этапе исполнения.

Рассмотрим пример. Все транспортные средства можно разделить на три категории: наземные, воздушные и водные. Затем, двигаясь вниз по иерархии, категории можно сделать более специализированными.

На рис.10.1. Рассмотрена подобная специализация.

Приведенный рисунок иллюстрирует несколько интересных черт, присущих любой иерархии та­кого типа:

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

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

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