Главная Случайная страница


Категории:

ДомЗдоровьеЗоологияИнформатикаИскусствоИскусствоКомпьютерыКулинарияМаркетингМатематикаМедицинаМенеджментОбразованиеПедагогикаПитомцыПрограммированиеПроизводствоПромышленностьПсихологияРазноеРелигияСоциологияСпортСтатистикаТранспортФизикаФилософияФинансыХимияХоббиЭкологияЭкономикаЭлектроника






Файловая структура Java-проекта

Java-проект может состоять из нескольких пакетов. Каждому пакету в файловой структуре операционной системы соответствует одна папка.

В пакете могут содержаться классы и интерфейсы. Они хранятся в файлах с расширением .java.

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

Eclipse создает новый файл с расширением .java автоматически, если выполнить команду New --> Class или New --> Interface.

Области видимости классов

Область видимости класса — это участок программы, в котором можно объявлять переменные и создавать объекты этого класса.

Обычный класс всегда виден в пределах своего пакета. Если класс является открытым, он виден также из других пакетов (в этом случае к нему надо обращаться, используя полное имя или, если предварительно импортировать пакет, сокращенное).

Вложенные классы, объявленные без модификатора public, видны только в методах содержащего их класса. Классы, описанные в методах, видны только в пределах этих методов.

Анонимные классы видны лишь в пределах команды, которой они создаются.

Области видимости членов класса

Члены класса (методы и атрибуты), объявленные как public, видны везде, где виден сам класс.

Члены класса, объявленные как protected видны в самом классе и его потомках.

Члены класса, объявленные как private, видны только в пределах класса.

Если к члену класса не применяется ни один из модификаторов public, private, protected, он виден в пределах текущего пакета.

"Видимость" поля означает, что его можно использовать в выражениях, передавать в качестве аргумента в методы, изменять его значение с помощью присваивания.

"Видимость" метода означает возможность его вызова.

Для обращения к полям и методам класса используется полное имя, состоящее из имени объекта соответствующего класса и собственно имени атрибута или метода. В теле метода того же класса имя объекта можно опускать (если подразумевается this — объект, для которого вызван данный метод).

Области видимости переменных

Переменные, объявленные в теле метода, видны от места объявления до конца блока, в котором это объявление находится. Границы блока задаются фигурными скобками {}. Поэтому в следующем примере:

{int x = 0;}{int x = 2;}

используются две разные переменные x (первая переменная, равная 0, перестает существовать за границами своего блока).

Переменные, являющимися параметрами метода, видны во всем теле метода.

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

int x = 0;{int x = 2;}

Нельзя, в частности, объявлять в теле метода переменную, совпадающую (по имени) с одним из параметров метода.

Конфликты имен

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

Конфликт имен возникает, когда импортируются два пакета, содержащие классы с одинаковыми именами.

В этом случае Java отдает предпочтение классу, который был импортирован первым. Для обращения к остальным классам следует использовать их полные имена.

Java "просматривает" имена классов в следующем порядке. Сначала — классы, импортированные поодиночке. Потом — классы, определенные в данном пакете. В последнюю очередь классы из пакетов, импортируемых полностью в порядке следования команд import.

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

 

Коллекции Java. Паттерн проектирования Iterator

Коллекции

Для хранения большого количества однотипных данных могут использоваться массивы, но они не всегда являются идеальным решением. Во-первых, длина массива задается заранее и в случае, если количество элементов заранее неизвестно, придется либо выделять память «с запасом», либо предпринимать сложные действия по переопределению массива. Во-вторых, элементы массива имеют жестко заданное размещение в его ячейках, поэтому, например, удаление элемента из массива не является простой операцией.

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

Язык Java предоставляет библиотеку стандартных коллекций, которые собраны в пакете java.util, поэтому нет необходимости программировать их самостоятельно.

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

Чтобы выбрать коллекцию, которая лучше всего подходит условию задачи, необходимо знать особенности каждой из них. Эти знания являются обязательными для любого программиста, поскольку без применения тех или иных коллекций редко обходится любая современная задача. Коллекции в библиотеке java.util представлены набором классов и интерфейсов.

 

Классы-коллекции

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

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

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

Некоторые коллекции в пакете java.utils не представлены самостоятельными классами. Например, очередь и список. Но для этих полезных структур данных определены соответствующие интерфейсы, то есть можно пользоваться любым классом, реализующим такой интерфейс.

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

Интерфейс Collection

Интерфейс Collection содержит набор общих методов, которые используются в большинстве коллекций. Рассмотрим основные из них.

add(Object item) — добавляет в коллекцию новый элемент. Метод возвращает true, если добавление прошло удачно и false — если нет. Если элементы коллекции каким-то образом упорядочены, новый элемент добавляется в конец коллекции.

clear() — удаляет все элементы коллекции.

contains(Object obj) — возвращает true, если объект obj содержится в коллекции и false, если нет.

isEmpty() — проверяет, пуста ли коллекция.

remove(Object obj) — удаляет из коллекции элемент obj. Возвращает false, если такого элемента в коллекции не нашлось.

size() — возвращает количество элементов коллекции.

Интерфейс List

Интерфейс List описывает упорядоченный список. Элементы списка пронумерованы, начиная с нуля и к конкретному элементу можно обратиться по целочисленному индексу. Интерфейс List является наследником интерфейса Collection, поэтому содержит все его методы и добавляет к ним несколько своих:

add(int index, Object item) — вставляет элемент item в позицию index, при этом список раздвигается (все элементы, начиная с позиции index, увеличивают свой индекс на 1);

get(int index) — возвращает объект, находящийся в позиции index;

indexOf(Object obj) — возвращает индекс первого появления элемента obj в списке;

lastIndexOf(Object obj) — возвращает индекс последнего появления элемента obj в списке;

set(int index, Object item) — заменяет элемент, находящийся в позиции index объектом item;

subList(int from, int to) — возвращает новый список, представляющий собой часть данного (начиная с позиции from до позиции to-1 включительно).

Интерфейс Set

Интерфейс Set описывает множество. Элементы множества не упорядочены, множество не может содержать двух одинаковых элементов. Интерфейс Set унаследован от интерфейса Collection, но никаких новых методов не добавляет. Изменяется только смысл метода add(Object item) — он не станет добавлять объект item, если он уже присутствует во множестве.

Интерфейс Queue

Интерфейс Queue описывает очередь. Элементы могут добавляться в очередь только с одного конца, а извлекаться с другого (аналогично очереди в магазине). Интерфейс Queue так же унаследован от интерфейса Collection. Специфические для очереди методы:

poll() — возвращает первый элемент и удаляет его из очереди.

peek() — возвращает первый элемент очереди, не удаляя его.

offer(Object obj) — добавляет в конец очереди новый элемент и возвращает true, если вставка удалась.

Иерархия классов - коллекций

Классы-коллекции являются наследниками абстрактного класса AbstractCollection. Иерархия этих классов приведена на рисунке (синим цветом показаны интерфейсы). Мы рассмотрим те из них, которые представляют наибольший практический интерес.

Класс Vector

Vector (вектор) — набор упорядоченных элементов, к каждому из которых можно обратиться по индексу. По сути эта коллекция представляет собой обычный список. Класс Vector реализует интерфейс List, основные методы которого названы выше. К этим методам добавляется еще несколько. Например, метод firstElement() позволяет обратиться к первому элементу вектора, метод lastElement() — к его последнему элементу. Метод removeElementAt(int pos) удаляет элемент в заданной позиции, а метод removeRange(int begin, int end) удаляет несколько подряд идущих элементов. Все эти операции можно было бы осуществить комбинацией базовых методов интерфейса List, так что функциональность принципиально не меняется.

Класс ArrayList

Класс ArrayList — аналог класса Vector. Он представляет собой список и может использоваться в тех же ситуациях. Основное отличие в том, что он несинхронизирован и одновременная работа нескольких параллельных процессов с объектом этого класса не рекомендуется. В обычных же ситуациях он работает быстрее.

Класс Stack

Stack — коллекция, объединяющая элементы в стек. Стек работает по принципу LIFO (последним пришел — первым ушел). Элементы кладутся в стек «друг на друга», причем взять можно только «верхний» элемент, т.е. тот, который был положен в стек последним. Для стека характерны операции, реализованные в следующих методах класса Stack:

push(Object item) — помещает элемент на вершину стека;

pop() — извлекает из стека верхний элемент;

peek() — возвращает верхний элемент, не извлекая его из стека;

empty() — проверяет, не пуст ли стек;

search(Object item) — ищет «глубину» объекта в стеке. Верхний элемент имеет позицию 1, находящийся под ним — 2 и т.д. Если объекта в стеке нет, возвращает -1.

Класс Stack является наследником класса Vector, поэтому имеет все его методы (и, разумеется, реализует интерфейсList). Однако если в программе нужно моделировать именно стек, рекомендуется использовать только пять вышеперечисленных методов.

Класс LinkedList

LinkedList— двунаправленный список, реализующий интерфейсы Listи Queue.

 

Последнее изменение этой страницы: 2016-07-23

lectmania.ru. Все права принадлежат авторам данных материалов. В случае нарушения авторского права напишите нам сюда...