Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Выч. тех. - Лаба-4.docx
Скачиваний:
3
Добавлен:
12.11.2018
Размер:
635.57 Кб
Скачать

Реализация методов интерфейса как закрытых методов

Другая стратегия реализации состоит в том, чтобы все или некоторые методы интерфейса сделать закрытыми. Для реализации этой стратегии класс, наследующий интерфейс, объявляет методы без модификатора доступа, что по умолчанию соответствует модификатору private, и уточняет имя метода именем интерфейса. Давайте создадим класс с именем PrivateInterfaces, являющийся аналогом только что рассмотренного класса SimpleText. В этом классе методы наследуемого интерфейса будут реализованы как закрытые для клиентов методы. Полного описания этого класса приводить не буду, ограничусь лишь некоторыми фрагментами. Вот как выглядят заголовки методов, реализующих методы интерфейса:

//Реализация интерфейсов как закрытых методов

string IStrings.Convert()

string IStrings.Cipher(string[] code)

Модификатор доступа стал по умолчанию private, а имя метода уточнено именем интерфейса. Интересно то, как теперь эти методы вызываются в методах класса. Их нельзя, как ранее, вызвать по имени или даже по полному имени. Нужно явно задать цель вызова. В качестве цели следует взять текущий объект this и привести его к типу интерфейса, так что получается вот такая сложная конструкция целевого объекта:

((IStrings)this)

Соответствующие строки кода в методах класса IsPalindrom и Coding выглядят теперь так:

string txt = ((IStrings)this).Convert();

return ((IStrings)this).Cipher(codeTable);

Класс PrivateInterface реализовал методы интерфейса IStrings, но сделал их закрытыми и недоступными для клиентов и наследников класса. Как же им получить доступ к закрытым методам? Есть два способа решения этой проблемы.

Обертывание. В классе, реализующем интерфейс, создается открытый метод, являющийся оберткой закрытого метода.

Кастинг. У клиента создается объект интерфейсного класса IStrings, полученный приведением (кастингом) объекта класса PrivateInterface. Этому объекту доступны закрытые методы интерфейса.

Обертывание - это широко распространенный прием в ООП. Под обертыванием понимают создание открытых методов класса, содержащих вызовы старых или недоступных клиентам методов. Цели обертывания могут быть различными. Например, имеется библиотека процедур, написанная на языке С или другом не объектном языке программирования. Эта библиотека весьма полезна, но недоступна в существующем виде. Использование обертывания позволяет обернуть ее в одежды класса, а каждую процедуру библиотеки превратить в метод класса. Иногда обертывание старого метода делается с целью изменения его интерфейса, сделав его более современным.

Фактически обертывание уже применялось при создании методов IsPalindrom и Coding. Давайте выполним обертку закрытых методов интерфейса, полностью сохранив их интерфейс, но изменив имена:

//Обертка методов интерфейса с переименованием

public string ClassConvert()

{

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

}

public string ClassCipher(string[] code)

{

return ((IStrings)this).Cipher(code);

}

Какая цель достигается в этом случае? Такой прием позволяет переименовывать методы интерфейса. Метод интерфейса со своим именем закрывается, а потом открывается под тем именем, которое класс выбрал для него. Как видите, методы переименованы и получили другие имена, под которыми они и будут известны и доступны клиентам класса.

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

Построим в классе Testing тест, аналогичный тесту TestText, для работы с объектом класса PrivateInterface.

/// <summary>

/// тестирование класса PrivateInterface

/// </summary>

public void TestTextPrivateInterface()

{

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

PrivateInterface privateInterface = new PrivateInterface(PAL);

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

string text;

text = privateInterface.ClassConvert();

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

if (privateInterface.IsPalindrom())

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

text = privateInterface.Coding();

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

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

IStrings istrings;

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

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

privateInterface = new PrivateInterface(text);

istrings = (IStrings)privateInterface;

text = istrings.Convert();

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

text = istrings.Cipher(CODE);

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

}

В этом тесте объект класса privateInterface вызывает метод интерфейса под новым именем ClassConvert, а интерфейсный объект istrings вызывает методы интерфейса, несмотря на то, что они закрыты, под собственными именами. Результаты работы теста показаны на. рис. 5.2.

Рис. 5.2. Реализация методов интерфейса как закрытых методов класса