Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка_ООП_2010.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.81 Mб
Скачать

6.2.4Использование обобщений Java 5

Обобщения (generics) идеологически подобны шаблонам С++, хотя имеют другую внутреннюю реализацию. Целесообразность их использования в рамках данной лабораторной работы вытекает из сделанного выше примечания, а именно, что коллекции содержат ссылки типа Object и поэтому при выборе элемента коллекции его приходится специально типизировать.

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

Общая структура использования настраиваемых коллекций следующая:

  1. В описании узла дерева необходимо создать и инициализировать коллекцию настраиваемый список, например

    class ListNode implements INode{

    //Информационные поля для узла дерева

    List<INode> listSon = new ArrayList<INode>();

    //Методы узла дерева

    }

  2. Доступ к сыну узла дерева элементу списка с индексом i выполняется следующим образом

node = listSon.get(i);//не требуется приведение типов

Следует обратить внимание на отсутствие специальной типизации ссылки, получаемой из коллекции. Однако если использовать конструкцию

node = (INode)listSon.toArray()[i];

то требуется типизация, т.к. toArray() возвращает Object и тем самым разрушает настройки List<INode>.

6.2.5Сериализация и десериализация дерева в файл

Сериализация (serialization) – это процесс записи состояния объекта в форме байтового потока. Позднее объект можно восстановить, используя процесс десериализации (deserialization).

Средства сериализации и десериализации разработаны для работы с объектами, расположенными в вершине ориентированного, возможно циклического, графа связей между объектами. Дерево является частным случаем такого графа.

Если выполняется сериализация объекта, расположенного в вершине ориентированного графа, то все другие - связанные с ним, объекты выстраиваются в рекурсивную последовательность и сериализуются. Аналогично в процессе десериализации все эти объекты и их ссылки будут восстанавливаться в правильную иерархическую структуру.

Интерфейс Serializable. Чтобы объект мог быть сериализован, его класс должен реализовать этот интерфейс. Сам интерфейс никаких методов не определят, он только указывает, что объект может быть сериализован без дополнительных уточнений (контроля) программиста. Если класс сериализован, то все его подклассы также сериализованы.

Интерфейс ObjectOutput. Расширяет интерфейс DataOutput и поддерживает сериализацию объектов. Содержит несколько методов. Наиболее интересным является метод void writeObject (Object obj). Он вызывается, чтобы сериализовать объект.

Класс ObjectOutputStream. Расширяет интерфейс OutputStream и реализует интерфейс ObjectOutput. Класс обеспечивает запись объектов в поток. Конструктор этого класса имеет вид:

ObjectOutputStream (OutputStream outStream) throws IOException,

где outStream - выходной поток, в который записываются сериализованные объекты.

Интерфейс ObjectInput. Расширяет интерфейс DataIntput и поддерживает десериализацию объектов. Содержит несколько методов. Наиболее интересным является метод Object readObject (). Он вызывается, чтобы десериализовать объект.

Класс ObjectInputStream. Расширяет интерфейс InputStream и реализует интерфейс ObjectInput. Класс обеспечивает чтение объектов из потока. Конструктор этого класса имеет вид

ObjectInputStream(InputStream inStream) throws IOException, StreamCorruptedException,

где inStream - входной поток, из которого считываются сериализованные объекты.

Общая структура использования сериализации следующая:

  1. Подключить библиотеку java.io.* и указать, что соответствующий класс реализует интерфейс Serializable;

    import java.io.*;

    class ListTree implements ITree, Serializable{

    //тело класса

    }

  2. Для сериализации объекта класса ListTree, необходимо создать поток вывода в файл и провести запись объекта в этот поток:

FileOutputStream fos = new FileOutputStream ("TreeSerial");

ListTree tree = new ListTree();

//Операции по заполнению дерева

try{

//создаем поток вывода для сериализации объекта tree

ObjectOutputStream out = new ObjectOutputStream(

new FileOutputStream("tree.dat"));

out.writeObject(tree); //сериализуем объект

out.close(); //закрываем поток

}

catch(IOException e){

//обработка исключительной ситуации

}

Общая структура использования десериализации во многом подобна структуре использования сериализации и очевидна из приводимого ниже текста:

try{

//создаем поток ввода для десериализации объекта tree

ObjectInputStream in = new ObjectInputStream(

new FileInputStream("tree.dat"));

tree=(ListTree)in.readObject(); //десериализуем объект

in.close(); //закрываем поток

}

catch(IOException e){

//обработка исключений

}