Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






Склеивание и переименование




Приведу пример двух интерфейсов, имеющих методы с одинаковой сигнатурой, и класса - наследника этих интерфейсов, применяющего разные стратегии для конфликтующих методов. У нас уже определен интерфейс IStrings. Предположим, что существует интерфейс ITransform, подобный Istrings:

interface ITransform

{

/// <summary>

/// Преобразование

/// </summary>

/// <returns>результат преобразования</returns>

string Convert();

 

/// <summary>

/// Шифрование

/// </summary>

/// <param name="code">код </param>

/// <returns>результат шифрования</returns>

string Cipher(string[] code);

}

 

У этих интерфейсов имена и сигнатуры методов совпадают. Вот класс, наследующий оба интерфейса:

/// <summary>

/// Наследник двух интерфейсов,

/// у методов которых Convert и Cipher

/// сигнатуры совпадают.

/// Методы Cipher склеиваются,

/// Convert - переименовываются

/// </summary>

class TwoInterfaces:IStrings,ITransform

{

//Опущена часть класса, общая с классом SimpleText

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

string IStrings.Convert()

{

string res = "";

foreach (char sym in text)

if (sym!= ' ') res += sym.ToString();

res = res.ToLower();

return res;

}

string ITransform.Convert()

{

string res = "";

for (int i = text.Length - 1; i >= 0; i--)

res += text[i];

return res;

}

//Переименование закрытых методов

public string ConvertOne()

{

return ((IStrings)this).Convert();

}

public string ConvertTwo()

{

return ((ITransform)this).Convert();

}

//Склеивание метода Cipher двух интерфейсов

public string Cipher(string[] code)

{

string s = text;

string res = "";

foreach (char sym in s)

{

int k = code[0].IndexOf(sym);

if (k >= 0) res += code[1][k];

else res += sym.ToString();

}

return res;

}

}

 

Для методов Cipher двух интерфейсов выбрана стратегия склеивания. Для методов Convert выбрана стратегия переименования. Методы интерфейсов реализованы как закрытые методы, а затем в классе объявлены два новых метода с разными именами, являющиеся обертками закрытых методов класса.

Приведу пример работы с объектами класса и интерфейсными объектами:

public void TestTextTwoInterfaces()

{

Console.WriteLine("Работа с объектом класса TwoInterfaces! ");

TwoInterfaces twoInterfaces = new TwoInterfaces(PAL);

Console.WriteLine("Исходный текст: " + PAL);

string text;

text = twoInterfaces.ConvertOne();

Console.WriteLine("Первое преобразование: " + text);

if (twoInterfaces.IsPalindrom())

Console.WriteLine("Это палиндром!");

text = twoInterfaces.ConvertTwo();

Console.WriteLine("Второе преобразование: " + text);

text = twoInterfaces.Coding();

Console.WriteLine("Шифрованный текст: " + text);

 

text = "Это простой текст!";

Console.WriteLine("Исходный текст: " + text);

twoInterfaces = new TwoInterfaces(text);

IStrings istrings;

ITransform itransform;

istrings = (IStrings)twoInterfaces;

itransform = (ITransform)twoInterfaces;

 

Console.WriteLine("Работа с объектом интерфейса IStrings!");

text = istrings.Convert();

Console.WriteLine("Преобразованный текст: " + text);

text = istrings.Cipher(CODE);

Console.WriteLine("Шифрованный текст: " + text);

 

Console.WriteLine("Работа с объектом интерфейса ITransform!");

text = itransform.Convert();

Console.WriteLine("Преобразованный текст: " + text);

text = itransform.Cipher(CODE);

Console.WriteLine("Шифрованный текст: " + text);

}

Результаты работы показаны на рис. 5.4.

Рис. 5.4. Решение проблемы коллизии имен

Интерфейсы и поля

Можно ли в интерфейсе объявлять не только методы, но и поля, обязательные для реализации потомками интерфейса? Ответ не однозначный: и да, и нет. Нет - потому что в явном виде в интерфейсе нельзя объявить поле. Да - потому что в интерфейсе можно объявить метод-свойство с процедурами get и set, обеспечивающими доступ к полю.

Вот пример такого интерфейса:

/// <summary>

/// Доступ к полям Name и Age

/// </summary>

interface IFields

{

string Name { get; set; }

int Age {get;}

}

 

Создадим класс, наследующий этот интерфейс:

/// <summary>

/// Класс, наследующий интерфейс IFields

/// Имеет поля Name и Age,

/// доступ к полю Name открыт клиентам класса,

/// доступ к полю Age закрыт и открыт с переименованием!

/// </summary>

class TwoFields:IFields

{

string name;

int age;

public TwoFields()

{

name = "Nemo"; age = 37;

}

public TwoFields(string name, int age)

{

this.name = name; this.age = age;

}

public string Name

{

get { return name; }

set { name = value; }

}

int IFields.Age

{

get { return age; }

}

public int WhatAge()

{

return age;

}

}

Обратите внимание: методы доступа к полям, наследуемые от интерфейса, можно реализовать как открытые и как закрытые, открывая их затем под другим именем. У класса всегда должна быть возможность переименовывать имена методов и полей, наследуемых от интерфейса.

Добавим в класс Testing новый метод, позволяющий протестировать работу с наследуемыми полями.

public void TestFields()

{

Console.WriteLine("Работа с объектом класса TwoFields!");

TwoFields twofields = new TwoFields();

Console.WriteLine("Имя: {0}, Возраст: {1}",

twofields.Name, twofields.WhatAge());

twofields.Name = "Captain Nemo";

Console.WriteLine("Работа с интерфейсным объектом IFields!");

IFields ifields = (IFields)twofields;

Console.WriteLine("Имя: {0}, Возраст: {1}",

ifields.Name,ifields.Age);

}

Результаты работы теста показаны на рис. 5.5.

Рис. 5.5. Поля, наследуемые от интерфейса IFields






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных