Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky.rtf
Скачиваний:
27
Добавлен:
22.03.2016
Размер:
11.9 Mб
Скачать

Interface iSeries {

Void setBegin(); // восстановить начальное состояние

Int GetNext { get; } // вернуть очередной член ряда

Int this[int k] {get;} // вернуть к-й член ряда

}

Договоримся о ролях прототипов, входящих в этот интерфейс. В приведённом

объявлении: setBegin() – прототип метода; GetNext – имя свойства, позволяющего

получить значение очередного члена ряда и настроить объект на следующий член.

Индексатор в этом примере позволяет получить значение не очередного, а

произвольного k-го члена ряда и перевести объект в состояние, при котором

свойство GetNext вернёт значение (k+1)-го члена.

Те функциональные возможности, которые приписаны членам интерфейса

ISeries, при реализации в конкретных классах могут быть изменены. Но в этом

случае нарушается общий принцип применения интерфейсов. Поэтому в примерах

конкретных классов будем придерживаться описанных соглашений о ролях членов

интерфейса ISeries.

Интерфейс ISeries можно реализовать для представления разных числовых

рядов. Вот, например, регулярные числовые последовательности, которые можно

представить классами, реализующими интерфейс ISeries:

1,1,2,3,5,8,13, … – Ряд Фибоначчи: ai=ai-2+ai-1, где i>2; a1=1, a2=1;

1,3,4,7,11,18,29, … – Ряд Лукаса: ai=ai-2+ai-1, где i>2; a1=1, a2=3;

1,2,5,12,29,70, … – Ряд Пелла: ai=ai-2+2*ai-1, где i>2; a1=1, a2=2.

В следующей программе на основе интерфейса ISeries определен класс,

представляющий в виде объектов фрагменты ряда Пелла (см. также рис 14.2).

// 14_02.cs - Интерфейс и его реализация

using System;

Interface iSeries // интерфейс числовых рядов

{

void setBegin( ); // задать начальное состояние

int GetNext { get; } // вернуть очередной член ряда

int this[int k] { get; } // вернуть к-й член ряда

}

class Pell : ISeries // Ряд Пелла: 1, 2, 5, 12,...

{

int old, last; // два предыдущих члена ряда

public Pell() { setBegin( ); } // конструктор

public void setBegin( ) // задать начальное состояние

{ old = 1; last = 0; }

public int GetNext // вернуть следующий после last

{

get {

int now = old + 2 * last;

old = last; last = now;

return now;

}

}

public int this[int k] // вернуть к-й член ряда

{

get {

int now = 0;

setBegin( );

if (k <= 0) return -1;

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

now = GetNext;

return now;

}

}

public void seriesPrint(int n)

{ // вывести n членов, начиная со следующего

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

Console.Write(GetNext + "\t");

Console.WriteLine( );

}

}

class Program

{

static void Main()

{

Pell pell = new Pell( );

pell.seriesPrint(9);

Console.WriteLine("pell[3] = " + pell[3]);

pell.seriesPrint(4);

pell.seriesPrint(3);

}

}

Результат выполнения программы:

1 2 5 12 29 70 169 408

985

pell[3] = 5

12 29 70 169

408 985 2378

Кроме реализации членов интерфейса ISeries в классе Pell объявлен метод

seriesPrint( ). Он выводит значения нескольких членов ряда, следующих за текущим.

Количество членов определяет аргумент метода seriesPrint( ). После выполнения

метода состояние ряда изменится – текущим членом станет последний выведенны

й

член ряда. Обратите внимание, что при реализации индексатора нумерация членов

ряда начинается с 1.

Рис 14.2. Диаграмма классов с интерфейсом для программы 14_02.cs

Обратите внимание, что в реализации интерфейса заголовок метода должен

полностью совпадать с заголовком прототипа этого метода в интерфейсе (за

исключением появления модификатора доступа). Соответствие должно быть и при

реализации других членов интерфейса.

В наших примерах интерфейсы и реализующие их классы размещены в одном

файле. Если интерфейс объявлен не в том файле, где выполняется его реализация,

то объявление интерфейса необходимо снабдить соответствующим модификатором

доступа.

В приведённых выше программах классов Item и Pell была использована

неявная реализация членов интерфейсов

"интерфейс:неявная реализация

интерфейсов" . Термин "неявная" употребляется для обозначения того, что в

объявлении класса, реализующего интерфейс, не применяются квалифицированные

имена

членов

интерфейса

и

их

реализации

снабжаются

обязательным

модификатором public.

Когда один класс реализует несколько интерфейсов, возможны совпадения

имён членов из разных интерфейсов. Для разрешения такой конфликтной ситуации

в классе, реализующем интерфейс, используется квалифицированное имя члена

интерфейса. Здесь существует ограничение – такая реализация члена называется

явной и она не может быть открытой, то есть для неё нельзя использовать

модификатор public. Подробнее об особенностях явной реализации интерфейсов

можно узнать из работ [1, 2, 8].

Соседние файлы в папке CSBasicCourse2ndedPodbelsky