Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»
Книгу Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория» читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
Являясь клиентом универсального класса Node, наш класс сохраняет родовые параметры клиента и ограничения, накладываемые на них. Два поля класса — first и cursor — задают указатели на первый и текущий элементы списка. Операции над списком связываются с курсором, позволяя перемещать курсор по списку. Рассмотрим вначале набор операций, перемещающих курсор:
public void start ()
{ cursor = first; } public void finish ()
{
while (cursor.next!= null)
cursor = cursor.next;
}
public void forth()
{ if (cursor.next!= null) cursor = cursor.next; }
Операция start передвигает курсор к началу списка, finish — к концу, a forth — к следующему элементу справа от курсора. Операции finish и forth определены только для непустых списков. Конец списка является барьером, и курсор не переходит через барьер. Нарушая принципы ради краткости текста, я не привожу формальных спецификаций методов, записанных в тегах <summary>.
Основной операцией является операция добавления элемента с ключом в список. Возможны различные ее вариации, из которых рассмотрим только одну — новый элемент добавляется за текущим, отмеченным курсором. Вот текст этого метода:
public void add(К key, Т item)
{
Node<K, T> newnode = new Node<K, T>();
if (first == null)
{
first = newnode; cursor = newnode;
newnode.key = key; newnode.item = item;
}
else
{
newnode.next = cursor.next; cursor.next = newnode;
newnode.key = key; newnode.item = item;
}
}
Заметьте, аргументы метода имеют соответствующие родовые параметры, чем и обеспечивается универсальный характер списка. При добавлении элемента в список различаются два случая — добавление первого элемента и всех остальных.
Рассмотрим теперь операцию поиска элемента по ключу, реализация которой потребовала ограничения универсальности типа ключа к;
public bool findstart(К key)
{
Node<K, T> temp = first;
while (temp!= null)
{
if (temp.key.CompareTo(key) == 0) {cursor=temp;
return(true);}
temp= temp.next;
}
return (false);
}
Искомые элементы разыскиваются во всем списке. Если элемент найден, то курсор устанавливается на найденном элементе и метод возвращает значение true. Если элемента с заданным ключом нет в списке, то позиция курсора не меняется, а метод возвращает значение false, в процессе поиска для каждого очередного элемента списка вызывается допускаемый ограничением метод CompareTo интерфейса IComparable. При отсутствии ограничений универсальности вызов этого метода или операции эквивалентности приводил бы к ошибке, обнаруживаемой на этапе компиляции.
Два метода класса являются запросами, позволяющими извлечь ключ и элемент списка, который отмечен курсором:
public К Key ()
{
return (cursor.key);
}
public T Item()
{
return(cursor.item);
}
Давайте рассмотрим теперь тестирующую процедуру — клиента нашего списка, демонстрирующую работу со списками, в которых элементы и ключи имеют разные типы:
public void TestConstraint ()
{
OneLinkList<int, string> list1 = new OneLinkList
<int, string>();
list1.add(33, "thirty three"); list1.add (22, "twenty two");
if (list1.findstart(33)) Console.WriteLine ("33 — найдено!");
else Console.WriteLine("33 — не найдено!");
if (list1.findstart(22)) Console.WriteLine ("22 — найдено!");
else Console.WriteLine("22 — не найдено!");
if (list1.findstart(44)) Console.WriteLine ("44 — найдено!");
else Console.WriteLine("44 — не найдено!");
Person pers1 = new Person("Савлов", 25, 1500);
Person pers2 = new Person("Павлов", 35, 2100);
OneLinkList<string, Person> list2 = new OneLinkList
< string, Person>();
list2.add("Савл", pers1); list2.add("Павел", pers2);
if (list2.findstart("Павел")) Console.WriteLine ("Павел — найдено!");
else Console.WriteLine("Павел — не найдено!");
if (list2.findstart("Савл")) Console.WriteLine ("Савл — найдено!");
else Console.WriteLine("Савл — не найдено!");
if (list2.findstart("Иоанн")) Console.WriteLine ("Иоанн — найдено!");
else Console.WriteLine("Иоанн — не найдено!");
Person pers3 = new Person("Иванов", 33, 3000);
list2.add("Иоанн", pers3); list2.start ();
Person pers = list2.Item(); pers.PrintPerson();
list2.findstart("Иоанн"); pers = list2.Item();
pers.PrintPerson();
}
Рис. 22.5. Поиск в списке с ограниченной универсальностью
Обратите внимание на строки, где создаются два списка:
OneLinkList<int, string> list1 = new OneLinkList<int, string>();
OneLinkList<string, Person> list2 = new OneLinkList< string, Person>();
У списка list1 ключи имеют тип int, у списка list2 — string. Заметьте, оба фактических типа, согласно обязательствам, реализуют интерфейс IComparable, у первого списка тип элементов — string, у второго — Person. Все работает прекрасно. Вот результаты вычислений по этой процедуре:
Как справиться с арифметикой
Представьте себе, что мы хотим иметь специализированный вариант нашего списка, элементы которого допускали бы операцию сложения и одно из полей которого сохраняло бы сумму всех элементов, добавленных в список. Как задать соответствующее ограничение на класс?
Как уже говорилось, наличие ограничения операции, где можно было бы указать, что над элементами определена операция +, решало бы проблему. Но такого типа ограничений нет. Хуже того, нет и интерфейса INumeric, аналогичного IComparable, определяющего метод сложения Add. Так что нам не может помочь и ограничение наследования.
Вот один из возможных выходов, предлагаемых в такой ситуации. Стратегия следующая: определим абстрактный универсальный класс Calc с методами, выполняющими вычисления. Затем создадим конкретизированных потомков этого класса. В классе, задающем список с суммированием, введем поле класса Calc. При создании экземпляров класса будем передавать фактические типы ключа и элементов, а также соответствующий калькулятор, но уже не как тип, а как аргумент конструктора класса. Этот калькулятор, согласованный с типом элементов, и будет выполнять нужные вычисления. Давайте приступим к реализации этой стратегии. Начнем с определения класса Calc;
public abstract class Calc<T>
{
public abstract T Add(T a, T b);
public abstract T Sub(T a, T b);
public abstract T Mult(T a, T b);
public abstract T Div(T a, T b);
}
Наш абстрактный универсальный класс определяет четыре арифметические операции. Давайте построим трех его конкретизированных потомков:
public class IntCalc: Calc<int>
{
public override int Add(int a, int b) { return (a + b);}
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Гость Наталья17 июль 12:42 Сюжет увлекательный и затейный,читается легко,но кто убийца,сразу было понятно.... Дорога к Тайнику. Часть 1 - Мария Владимировна Карташева
-
Гость Дарья16 июль 23:19 Отличная книга. Без сцен 18+, что приятно. Легкий и приятный сюжет. Благоразумная ГГ, терпеливый и сдержанный ГГ. Прочла с... Королева драконов - Анна Минаева
-
Dora16 июль 17:16 Типичная история: она — многодетная, затюканная бытом. У нее имеется богатый и красивый муж, у которого завелась любовница, а... Я беременна от вашего мужа - Ольга Ивановна Коротаева