Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Стандартные интерфейсы .NET




Лекция 19. Стандартные интерфейсы. Клонирование. Итераторы

В библиотеке.NET определено множество стандартных интерфейсов, задающих желаемое поведение объектов. Например, интерфейс IComparable задает метод сравнения объектов по принципу больше или меньше, что позволяет выполнять их сортировку. Реализация интерфейсов IEnumerable и IEnumerator дает возможность просматривать содержимое объекта с помощью конструкции foreach, а реализация интерфейса ICloneable – клонировать объекты.

Стандартные интерфейсы поддерживаются многими стандартными классами библиотеки. Например, работа с массивами с помощью цикла foreach возможна именно потому, что тип Array реализует интерфейсы IEnumerable и IEnumerator. Можно создавать и собственные классы, поддерживающие стандартные интерфейсы, что позволит использовать объекты этих классов стандартными способами.

Сравнение объектов (интерфейс IComparable)

Интерфейс IComparable содержит всего один метод CompareTo(), возвращающий результат сравнения двух объектов – текущего и переданного ему в качеству параметра:

interface IComparable

{

int CompareTo(object obj)

}

Метод должен возвращать:

o 0, если текущий объект и параметр равны

o отрицательное число, если текущий объект меньше параметра

o положительное число, если текущий объект больше параметра

Пример использования стандартного интерфейса IComparable на примере класса Monster

namespace ConsoleApplication1

{

//создание класса, использующего интерфейс для сравнения элементов

class Monster: IComparable

{

public Monster(int сила, int умение, string имя)

{

this.сила = сила;

this.умение = умение;

this.имя = имя;

}

public void Passport()

{

Console.WriteLine("Монстр {0} сила = {1} умение= {2}", имя, сила, умение);

}

//обязательная реализация этого метода, т.к. он находится в интерфейсе

public int CompareTo(object obj)

{

Monster temp = (Monster)obj;

if (this.сила > temp.сила) return 1;

if (this.сила < temp.сила) return -1;

return 0;

}

string имя;

int сила, умение;

}

 

class Program

{

static void Main(string[] args)

{

const int n = 3;

Monster[] mas = new Monster[n]; //массив монстров

//инициализация каждого монстра(элемента массива)

mas[0] = new Monster(50, 50, "Вася");

mas[1] = new Monster(100, 100, "Петя");

mas[2] = new Monster(40, 10, "Игорь");

//Только теперь сортировка массива экземпляров класса Monster стала доступной, //благодаря методу CompareTo()

Array.Sort(mas);

//вывод элементов массива монстров

foreach (Monster x in mas)

x.Passport();

Console.ReadLine(); } } }

В данной программе критерием сортировки является поле сила для каждого монстра. То есть массив сортируется по возрастанию этого поля у всех экземпляров класса Monster.

Если несколько экземпляров имеют одинаковое значение критерия сортировки, то порядок их следования не изменится.

Во многих алгоритмах требуется выполнить сортировку по различным критериям. Для этого используется интерфейс IComparer.

Сортировка объектов по различным критериям (интерфейс IComparer)

Данный интерфейс определен в пространстве имен System.Collections. Он также содержит один метод Compare(), возвращающий результат сравнения двух объектов, переданных ему в качестве параметров.

interface IComparer

{

int Compare(object obj1,object obj2)

}

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

Модернизируем предыдущий пример и отсортируем массив экземпляров класса Monster по двум критериям – по именам (свойство Имя, класс SortByИмя) и умениям (свойство Умение, класс SortByУмение). Классы критериев сортировки объявлены вложенными, так как требуются только экземплярам класса Monster.

Пример использования стандартного интерфейса IComparer на примере класса Monster

using System;

using System.Collections;//обязательное подключение данного пространства имен

using System.Linq;

using System.Text;

namespace ConsoleApplication1

{

class Monster //обратите внимание на то, что класс не поддерживает интерфейс

{

public Monster(int сила, int умение, string имя)

{

this.сила = сила;

this.умение = умение;

this.имя = имя;

}

public int Умение

{

get { return умение; }

set

{

if (value > 0) умение = value;

else умение = 0;

}

}

public string Имя

{

get { return имя; }

}

 

public void Passport()

{

Console.WriteLine("Монстр {0} сила = {1} умение= {2}", имя, сила, умение);

}

//Создание ВЛОЖЕННОГО КЛАССА для сортировки по одному критерию

public class SortByИмя: IComparer

{

//вызов стандартного метода Compare() интерфейса и реализация его для сортировки по //имени

int IComparer.Compare(object obj1, object obj2)

{

Monster m1 = (Monster)obj1;

Monster m2 = (Monster)obj2;

return String.Compare(m1.Имя, m2.Имя);

}

}

//Создание второго ВЛОЖЕННОГО КЛАССА для сортировки по одному критерию

public class SortByУмение: IComparer

{

//вызов стандартного метода Compare() интерфейса и реализация его для сортировки по //умению

int IComparer.Compare(object obj1, object obj2)

{

Monster m1 = (Monster)obj1;

Monster m2 = (Monster)obj2;

if (m1.Умение > m2.Умение) return 1;

if (m1.Умение < m28Умение) return -1;

return 0;

 

}

}

string имя;

int сила, умение;

}

 

class Program

{

static void Main(string[] args)

{

const int n = 3;

Monster[] mas = new Monster[n];

//инициализация каждого монстра(элемента массива)

mas[0] = new Monster(50, 50, "Вася");

mas[1] = new Monster(100, 100, "Петя");

mas[2] = new Monster(40, 10, "Игорь");

Console.WriteLine("Сортировка по имени");

//метод Sort() вызывается с двумя параметрами!!!

//2-ой параметр – экземпляр класса Monster.SortByИмя – это полное имя класса!!!

Array.Sort(mas, new Monster.SortByИмя());

foreach (Monster x in mas)

x.Passport();

Console.WriteLine("Сортировка по умениям");

Array.Sort(mas, new Monster.SortByУмение());

foreach (Monster x in mas)

x.Passport();

Console.ReadLine(); } }}

Клонирование объектов (интерфейс ICloneable)

Клонирование -создание копии объекта. Копия объекта называется клоном. При присваивании одного экземпляра другому копируется ссылка, а не сам объект. Если необходимо скопировать в другую область памяти поля объекта, можно воспользоваться методом MemberwiseClone(), который любой объект наследует от класса object. При этом объекты, на которые указывают поля объекта, в свою очередь являющиеся ссылками, не копируются. Это называется поверхностным клонированием. Для создания полностью независимых объектов необходимо глубокое копирование, когда в памяти создается дубликат всего дерева объектов, то есть объектов, на которые ссылаются поля объекта, поля полей, и т.д. Алгоритм глубокого копирования сложен, требует рекурсивного обхода всех ссылок объекта и отслеживания циклических зависимостей.

Объект, имеющий собственные алгоритмы клонирования, должен объявляться как производный интерфейса ICloneable и переопределять его единственный метод Clone().

Модернизируем предыдущий пример и создадим поверхностную копию экземпляра класса Monster с помощью метода MemberwiseClone() и реализации интерфейса ICloneable. Метод MemberwiseClone() можно вызывать только из методов класса, так как он объявлен в классе object как protected.

using System;

using System.Collections;

using System.Linq;

using System.Text;

namespace ConsoleApplication1

{

class Monster:ICloneable

{

public Monster(int сила, int умение, string имя)

{

this.сила = сила;

this.умение = умение;

this.имя = имя;

}

public Monster ShallowClone()

{

return (Monster)this.MemberwiseClone();

}

public object Clone()

{

return new Monster(this.сила, this.умение, "Это-клон!" + this.имя);

}

public int Умение

{

get { return умение; }

set

{

if (value > 0) умение = value;

else умение = 0;

}

}

public void Passport()

{

Console.WriteLine("Монстр {0} сила = {1} умение= {2}", имя, сила, умение);

}

string имя;

int сила, умение;

}

class Program

{

static void Main(string[] args)

{ Monster Вася=new Monster (100,100,"Вася");

Monster X = Вася;

//2 способа создания клонов – метод ShallowClone() и Clone()

Monster Y = Вася.ShallowClone();

Monster Z = (Monster)Вася.Clone();

Чем отличается

Вася.Passport();

X.Passport();

Y.Passport();

Z.Passport();

Console.ReadLine(); } }}

 

Экземпляр X ссылается на ту же область памяти.ю что и экземпляр Вася. Следовательно, если внести изменения в один из этих объектов, это отразится на другом. Экземпляры Y и Z, созданные путем клонироания, обладают собственными копиями значений полей и независимы от исходного экземпляра.

 




Поделиться с друзьями:


Дата добавления: 2014-01-20; Просмотров: 7052; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.041 сек.