Помощь в написании студенческих работ
Антистрессовый сервис

Реализация интерфейсов. 
Программирование. 
Базовый курс с#

РефератПомощь в написанииУзнать стоимостьмоей работы

Когда один класс реализует несколько интерфейсов, возможны совпадения имен членов из разных интерфейсов. Для разрешения такой конфликтной ситуации в классе, реализующем интерфейс, используется квалифицированное имя члена интерфейса. Здесь существует ограничение — такая реализация члена называется явной и она не может быть открытой, т. е. для нее нельзя использовать модификатор public. Подробнее… Читать ещё >

Реализация интерфейсов. Программирование. Базовый курс с# (реферат, курсовая, диплом, контрольная)

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

Как и для абстрактных классов, невозможно определить объект с помощью интерфейса.

Чтобы интерфейсом можно было пользоваться, он должен быть реализован классом или структурой. В этой главе рассмотрим реализацию интерфейсов с помощью классов. Синтаксически отношение реализации интерфейса обозначается включением имени интерфейса в спецификацию базы класса. Напомним формат объявления класса со спецификацией базы (для простоты не указаны модификаторы класса):

class имя_класса спецификация_базы

{

объявления_членов_класса

}

Спецификация базы класса в этом случае имеет вид:

:имя_базового_классаор1, opt список_интерфейсоворt

Имя базового класса (и следующая за ним запятая) могут отсутствовать. В списке интерфейсов через запятые помещаются имена тех интерфейсов, которые должен реализовать класс. В спецификацию базы класса может входить только один базовый класс и произвольное число имен интерфейсов. При этом должно выполняться обязательное условие — класс должен реализовать все члены всех интерфейсов, включенных в спецификацию базы. Частный случай — класс, реализующий только один интерфейс:

class имя_класса: имя_интерфейса

{

объявления_членов_класса

У

Реализацией члена интерфейса является его полное определение в реализующем классе, снабженное модификатором доступа public.

Сигнатуры и типы возвращаемых значений методов, свойств и индексаторов в реализациях и в интерфейсе должны полностью совпадать.

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

В следующей программе (1401.cs) интерфейс IPublication реализуется классом Item — «заметка в газете».

// 1401.cs — Интерфейс и его реализация using System; interface IPublication { // интерфейс публикаций

void write (); // готовить публикацию

void readQ; // читать публикацию

string Title { set; get; } // название публикации

У

class Item: IPublication { // заметка в газете

string newspaper = «Известия»; // название газеты string headline; // заголовок статьи

public string Title { // реализация свойства set { headline = value; } get { return headline; }.

>

public void write ().

{// реализация метода

/* операторы, имитирующие подготовку статьи */

У

public void read ().

{ // реализация метода /* операторы, имитирующие чтение статьи */

Console.WriteLine (@" npo4en в газете «» {0}" «статью „“ {1}» «.», newspaper. Title);

}

}

class Program.

{

static void Main ().

{

Console.WriteLine («Publication!»); Item article = new Item (); article. Title = «О кооперации»; article. read ();

} }

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

Publication!

Прочел в газете «Известия» статью «О кооперации» .

Класс Item кроме реализаций членов интерфейса включает объявления закрытых полей: newspaper (название газеты) и headline (заголовок статьи). Для простоты в класс не включен конструктор и только условно обозначены операторы методов write () и read (). Реализация свойства Title приведена полностью — аксессоры get и set позволяют получить и задать название статьи, представляемой конкретным объектом класса Item. В методе Main () нет ничего незнакомого читателю — определен объект класса Item и ссылка article на него. С помощью обращения arcticle. Title задано название статьи.

В UML для изображения интерфейсов применяется та же символика, что и для классов (см. рис. 14.1). Конечно, имеется отличие — в верхней части, после имени интерфейса IPublication помещается служебное слово Interface. Тот факт, что класс реализует интерфейс, отображается с помощью специального символа и указанием имени интерфейса над прямоугольником, представляющим класс.

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

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

В качестве второго примера рассмотрим интерфейс, реализация членов которого позволит получать целочисленные значения членов числовых рядов [9]:

interface ISeries.

{

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

У

Поясним роли прототипов, входящих в этот интерфейс. В приведенном объявлении: setBegin () — прототип метода; GetNext — имя свойства, позволяющего получить значение очередного члена ряда и настроить объект на следующий член. Индексатор в этом примере позволяет получить значение не очередного, а произвольного k-го члена ряда и перевести объект в состояние, при котором свойство GetNext вернет значение (к+1)-го члена.

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

Интерфейс ISeries можно реализовать для представления разных числовых рядов. Вот, например, регулярные числовые последовательности, которые можно представить классами, реализующими интерфейс ISeries:

  • 1, 1, 2, 3, 5, 8, 13, … — ряд Фибоначчи: ai=ai_2+ai_1, где i > 2; аг= 1, а2= 1;
  • 1.3.4.7.11.18.29. .—ряд Лукаса: at= а^+а^, где! >2; ах =1, а2= 3;
  • 1.2.5.12.29.70. .—ряд Пелла: а* =а,_2 + 2 * а^_х, где i > 2; а1= 1, а2= 2. В следующей программе на основе интерфейса ISeries определен

класс, представляющий ряд Пелла (см. диаграмму на рис 14.2).

// 1402.cs — Интерфейс и его реализация using System;

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

{

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

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

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

У

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

{

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

public Pell () { setBeginQ; } 11 конструктор public void setBeginQ // задать начальное состояние { old = 1; last = 0; }.

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

{

get.

{

int now = old + 2 * last; old = last; last = now; return now;

} }

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

{

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 + ««);

Console.WriteLine ();

} }

class Program.

{

static void Main ().

{

Pell pell = new PellQ; 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_02.cs.

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

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

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

В приведенных выше программах классов Item и Pell была использована неявная реализация членов интерфейсов. Термин «неявная» употребляется для обозначения того, что в объявлении класса, реализующего интерфейс, не применяются квалифицированные имена членов интерфейса и их реализации снабжаются обязательным модификатором public.

Когда один класс реализует несколько интерфейсов, возможны совпадения имен членов из разных интерфейсов. Для разрешения такой конфликтной ситуации в классе, реализующем интерфейс, используется квалифицированное имя члена интерфейса. Здесь существует ограничение — такая реализация члена называется явной и она не может быть открытой, т. е. для нее нельзя использовать модификатор public. Подробнее об особенностях явной реализации интерфейсов можно узнать, например, из работ [1, 5].

Показать весь текст
Заполнить форму текущей работой