Студопедия

КАТЕГОРИИ:


Архитектура-(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)

Class Class1

Summary description for Class1.

Namespace Ch11ExO1

Using System. Collections

Public class Chicken: Animal

Public class Cow: Animal

Set

Get

Public string Name

Public abstract class Animal

Namespace Ch11ExO1

Использование семейств

Класс System.Collections.ArrayList — один из классов в пространстве имен System.Collections — тоже реализует интерфейсы IEnumerable, ICollection и IList, однако делает это более изощренным способом, чем класс System.Array. В то время как массивы обладают фиксированным размером (мы не имеем возможности добавлять или исключать элементы), этот класс может использоваться для представления списков элементов переменной длины. Чтобы получить представление о том, какими возможностями обладают такие усложненные семейства, давайте рассмотрим пример, в котором наряду с таким классом будет использоваться и обыкновенный массив.

Пример:

{

{

protected string name;

{

{

return name;

}

{

name = value;

}

}

public Animal()

{

name = "The animal with no name";

}

public Animal(string newName)

{

name = newName;

}

public void Feed()

{

Console.WriteLine("{0} has been fed.", name) ;

}

}

{

public void Milk()

{

Console.WriteLine(“{0} has been milked.”, name);

}

public Cow(string newName): base(newName)

{

}

{

public void LayEgg()

{

Console.WriteLine(“{0} has laid an egg.”, name);

}

public Chicken(string newName): base(newName)

{

}

}

}

Внесите следующие изменения в Classl.cs:

using System;

/// <summary>

/// </summary>

{

static void Main (string [] args)

{

Console.WriteLine(“Create an Array type collection of Animal” +

“objects and use it:”);

Animal [] animalArray = new Animal [2];

Cow myCow1 = new Cow(“Deirdre”);

animalArray[0] = myCow1;

animal Array [1] = new Chicken (“Ken”);

foreach (Animal myAnimal in animalArray)

{

Console.WriteLine(“New {0} object added to Array collection,” +

“Name = {1}”, myAnimal.ToString(), myAnimal.Name);

}

Console.WriteLine(“Array collection contains {0} objects”,

animalArray.Length);

animalArray[0].Feed();

((Chicken) animalArray [1]).LayEgg();

Console.WriteLine();

Console.WriteLine(“Creat an ArrayList type collection of Animal”+

“objects and use it:”);

ArrayList animalArrayList = new ArrayList();

Cow myCow2 = new Cow(“Hayley”);

animalArrayList.Add(myCow2);

animalArrayList.Add(new Chicken(“Roy”));

foreach (Animal myAnimal in animalArrayList)

{

Console.WriteLine(“New {0} object added to ArrayList collection,” +

Name = {1}”/ myAnimal.ToString (), my Animal. Name);

}

Console.WriteLine(“ArrayList collection contains {0} objects.”,

animalArrayList.Count);

((Animal) animalArrayList [0]).Feed();

((Chicken) animalArrayList [1]).LayEgg();

Console.WriteLine()

Console.WriteLine(“Additional manipulation of ArrayList:”);

animalArrayList.RemoveAt(0);

((Animal) animalArrayList [0]).Feed();

animalArrayList.AddRange(animalArray);

((Chicken)animalArrayList[2]).LayEgg();

Console.WriteLine(“The animal called {0} is at index {!}.”,

myCowl.Name, animalArrayList.IndexOf(myCow1));

myCowl.Name = “Janice”;

Console.WriteLine(“The animal is now called (0).”,

((Animal) animalArrayList [1]).Name);

}

}

}

В этом примере создается два семейства объектов, причем первое — с использованием класса System.Array (т. е. обыкновенный массив), а второе — с использованием класса System.ArrayList. Оба они являются семействами объектов класса Animal, который определен в файле Animal.cs. Класс Animal является абстрактным классом, следовательно, создание экземпляров этого класса является недопустимым; однако за счет использования полиморфизма имеется возможность включить в состав семейства экземпляры класса cow и класса chicken, которые являются производными от класса Animal. Эти массивы создаются в методе Main() в файле Class1.es, после чего над ними производятся различные манипуляции, показывающие их характеристики и возможности. Некоторые из продемонстрированных операций применимы как к семейству Array, так и к семейству ArrayList, хотя и имеются незначительные отличия в синтаксисе. Однако есть и такие операции, выполнение которых оказывается возможным только с более сложным типом ArrayList. Мы начнем с рассмотрения простых операций, сравнивая код и полученные результаты для обоих типов семейств.

Итак, первое — создание семейства. Для того чтобы использовать обычный массив, необходимо инициализировать его с фиксированными размерами. Мы выполняем эти действия над массивом с именем animalArray:

Animal [] animalArray = new Animal [2];

С другой стороны, для семейств ArrayList при инициализации задание размера не требуется, поэтому список (с именем animalArrayList) может быть создан следующим образом:

ArrayList animalArrayList = new ArrayList();

Существует два других конструктора, которые могут быть использованы для данного класса. Первый осуществляет копирование содержимого уже существующего семейства в новый экземпляр, при этом семейство передается ему в качестве параметра; второй конструктор позволяет задать емкость семейства и тоже посредством параметра. Эта емкость, задаваемая значением типа int, устанавливает начальное количество элементов, которые могут содержаться в данном семействе.

На самом деле это не является реальной емкостью семейства, поскольку емкость автоматически удваивается, если число элементов превышает заданное значение. В случае массивов, состоящих из элементов ссылочных типов (как используемые объекты класса Animal и производных от него классов), простая инициализация массива с указанием размера не влечет за собой инициализации его элементов. Для того чтобы воспользоваться некоторым вхождением, его также необходимо инициализировать, откуда следует, что элементам массива должны быть присвоены инициализированные объекты:

Cow myCow1 = new Cow(“Deirdre”);

animalArray[0] = myCow1;

animalArray[1] = new Chicken(“Ken”);

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

В семействе ArrayList не существует никаких элементов, даже ссылающихся на null. Это означает, что мы лишены возможности присваивать новые объекты аналогичным образом, с использованием индексов. Вместо этого для включения новых объектов необходимо воспользоваться методом Add() объекта ArrayList:

Cow myCow2 = new Cow (“Hayley”);

animalArrayList.Add(myCow2);

animalArrayList.Add (new Chicken (“Roy” ));

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

animalArrayList [0] = new Cow(“Alma”);

Правда, в настоящем примере мы таких действий предпринимать не будем.

Также можно использовать конструкцию foreach для прохода по элементам массива. Это оказывается возможным, поскольку класс System.Array реализует интерфейс IEnumerable, а единственный метод этого интерфейса, GetEnumerator(), позволяет проходить в цикле по всем элементам семейства. В нашей программе мы выводим информацию обо всех объектах класса Animal, содержащихся в массиве:

foreach (Animal myAnimal in animalArray)

{

Console.WriteLine(“New {0} object added to Array collection,” +

“Name = {1}”, myAnimal.ToString(), myAnimal.Name);

}

Объект ArrayList также поддерживает интерфейс IEnumerable и, следовательно, может использоваться вместе с конструкцией foreach:

foreach (Animal myAnimal in animalArrayList)

{

Console.WriteLine(“New {0} object added to ArrayList collection,” +

“Name = (1)”, myAnimal.ToString(), myAnimal.Name);

}

Далее для вывода на экран числа элементов, содержащихся в массиве, мы используем свойство массива Length:

Console.WriteLine(“Array collection contains {0} objects.”,

animalArray.Length);

Мы можем достигнуть того же самого результата и для семейства ArrayList, с тем лишь отличием, что придется воспользоваться свойством Сount, которое является составной частью интерфейса ICollection:

Console.WriteLine(“ArrayList collection contains {0} objects.”,

animalArrayList.Count);

Семейства — независимо от того, являются ли они массивами или более сложными семействами — оказываются не столь полезными, если в них не предусмотрено обеспечение доступа к принадлежащим им элементам. Простые массивы строго типизированы, т. е. они обеспечивают непосредственный доступ к типу своих элементов. Это означает, что можно напрямую вызывать метод их элемента:

animalArray[0].Feed();

Поскольку массив имеет абстрактный тип Animal, то нельзя непосредственно вызывать методы, предоставляемые производными классами. Вместо этого следует воспользоваться приведением типа:

((Chicken) animalArray [1]).LayEgg();

Семейство ArrayList — это семейство объектов класса System.Object (мы присвоили ему объекты Animal, воспользовавшись полиморфизмом). Это значит, что необходимо выполнить приведение типа для всех его элементов:

((Animal)animalArrayList[0]).Feed();

((Chicken)animalArrayList[1]).LayEgg();

В оставшейся части кода используются некоторые особенности семейства Animal, которые отсутствуют у семейства Array.

Во-первых, можно удалять элементы с помощью методов Remove() и RemoveAt(), которые являются составной частью реализации класса ArrayList. Эти методы производят удаление элемента из массива по ссылке и по индексу соответственно. В нашем примере для удаления первого включенного в список элемента — объекта класса Сow, свойство Name которого имеет значение "Hayley" — используется второй метод:

animalArrayList.RemoveAt(0);

В качестве альтернативы можно было бы применить следующий код:

animalArrayList.Remove(myCow2);

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

Как бы то ни было, единственным элементом, оставшимся в семействе, является объект класса Сhicken, доступ к которому мы осуществляем следующим образом:

((Animal)animalArrayList[0]).Feed();

Выполнение любых операций над элементами объекта ArrayList, в результате которых в этом массиве останется N элементов, будет производиться таким образом, что этим элементам будут соответствовать индексы в диапазоне от 0 до N-I.

Так, например, удаление элемента с номером 0 приводит к тому, что все остальные элементы сдвигаются в массиве на одну позицию, поэтому доступ к объекту класса Сhicken осуществляется с индексом 0, а не 1. А поскольку теперь в массиве не существует элемента с индексом 1 (с самого начала было всего два элемента), то при попытке выполнить следующий код будет сгенерирована исключительная ситуация:

((Animal)animalArrayList[1]).Feed();

Семейства ArrayList позволяют добавлять сразу по несколько элементов с помощью метода AddRange(). Этому методу может передаваться произвольный объект, обладающий интерфейсом ICollection, в который входит массив animalArray:

animalArrayList.AddRange(animalArray);

Теперь для подтверждения того, что это работает, мы можем попытаться осуществить доступ к третьему элементу семейства, который будет являться вторым элементом в animalArray:

((Chicken)animalArrayList[2]).LayEgg();

Метод AddRange() не является частью ни одного из интерфейсов, предоставляемых классом ArrayList. Этот метод присущ именно классу ArrayList и демонстрирует тот факт, что в классах семейств мы можем описывать определяемое пользователем поведение, которое далеко выходит за рамки рассмотренных выше интерфейсов. Этот класс предоставляет также множество других интересных интерфейсов, например, InsertRange(), который позволяет вставлять массив объектов в любую точку списка, а также методы для выполнения таких задач, как сортировка и изменение порядка следования элементов.

Наконец, мы вновь задействуем возможность использовать несколько ссылок на один и тот же объект. Применив метод Indexof(), являющийся частью интерфейса IList, мы можем узнать не только то, что теперь объект myCowl (который мы изначально добавили к массиву animalArray) входит в семейство animalArrayList, но также и каков его индекс:

Console.WriteLine(“The animal called {0} is at index {1}.”,

myCowl.Name, animalArrayList.IndexOf(myCowl));

Следующие две строки кода переименовывают объект с помощью ссылки на него и выводят новое имя на экран, используя для этого ссылку семейства:

myCowl.Name = “Janice”;

Console.WriteLine(“The animal is now called {0}.”,

((Animal) animalArrayList [1]).Name);

Определение семейств

Также необходимо узнать, каким образом можно создавать собственные строго типизированные семейства.

Один из способов — это реализовать все необходимые методы вручную, однако такой подход может потребовать очень больших затрат времени, а в некоторых случаях оказаться чрезвычайно сложным. В качестве альтернативы существует возможность создать семейство, являющееся производным от некоторого класса, например, от System.Collections.CollectionBase — абстрактного класса, в котором реализована большая часть семейств. Мы рекомендуем использовать именно такой способ.

Класс CollectionBase предоставляет интерфейсы IEnumerable, ICollection и IList, однако в них реализованы только некоторые из необходимых методов, а именно методы Clear() и RemoveAt() интерфейса IList, а также свойство Count интерфейса ICollection. Если возникает необходимость в каких-либо дополнительных функциональных возможностях, то их приходится реализовывать самостоятельно.

Для этого в классе CollectionBase предусмотрено два защищенных свойства, которые позволяют осуществлять доступ собственно к хранящимся объектам. Можно воспользоваться свойством List — оно обеспечивает доступ к элементам посредством интерфейса IList, и свойством InnerList — оно является объектом ArrayList и используется доя хранения элементов.

Например, класс семейства для хранения объектов Animal может быть в общих чертах определен следующим образом (вскоре мы познакомимся с более полным определением):

<== предыдущая лекция | следующая лекция ==>
Семейства | Namespace ChllExO2
Поделиться с друзьями:


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


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



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




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