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

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

Можно ли в интерфейсе объявлять не только методы, но и поля, обязательные для реализации потомками интерфейса? Ответ не однозначный: и да, и нет. Нет - потому что в явном виде в интерфейсе нельзя объявить поле. Да - потому что в интерфейсе можно объявить метод-свойство с процедурами 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

Встроенные интерфейсы

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

Упорядоченность объектов и интерфейс iComparable

Часто, когда создается класс, желательно задать отношение порядка на его объектах. Такой класс следует объявить наследником интерфейса IComparable. Этот интерфейс имеет всего один метод CompareTo (object obj), возвращающий целочисленное значение, положительное, отрицательное или равное нулю, в зависимости от выполнения отношения "больше", "меньше" или "равно".

Как правило, в классе вначале определяют метод CompareTo, а после этого вводят перегруженные операции, чтобы выполнять сравнение объектов привычным образом с использованием знаков операций отношения.

Давайте введем отношение порядка на классе Person, рассмотренном в лекции 1, сделав этот класс наследником интерфейса IComparable. Реализуем в этом классе метод интерфейса CompareTo:

public class Person:IComparable

{

public int CompareTo( object pers)

{

const string s = "Сравниваемый объект не принадлежит классу Person";

Person p = pers as Person;

if (!p.Equals(null))

return (fam.CompareTo(p.fam));

throw new ArgumentException (s);

}

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

}

Поскольку аргумент в методе интерфейса принадлежит типу object, перед выполнением сравнения его нужно привести к типу Person. Для приведения используется операция as, позволяющая проверить корректность выполнения приведения. Если приведение невозможно, то невозможно выполнить и сравнение объектов. В этом случае выбрасывается исключение, которое может обработать разумным образом только клиент класса, пытавшийся выполнить сравнение. В самом классе Person можно только пояснить ситуацию, передав информацию объекту исключения.

Заметьте также, что при проверке на значение null используется отношение Equals, а не обычное равенство, которое будет переопределено.