Перейти к содержимому

Что такое пакет в программировании

  • автор:

Учебники. Программирование для начинающих.

Кресла офисные Chairman В ассортименте нашей компании представлены как готовые мебельные комплекты для офиса со всеми составляющими для обустройства полноценного рабочего места, так и отдельные предметы обстановки. Наша офисная мебель предназначена для размещения в кабинетах руководителей, помещениях для встреч и конференций, приемных, ресепшн-зонах. Если в офисе предусмотрена область для спонтанного сотрудничества, фуршетов, семинаров, презентаций, мастер-классов, у нас вы сможете выбрать мебель.

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

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

Cамоучитель по Java

Глава 3. Пакеты и интерфейсы

Пакет и подпакет

В стандартную библиотеку Java API входят сотни классов. Каждый программист в ходе работы добавляет к ним десятки своих. Множество классов становится необозримым. Уже давно принять классы объединять в библиотеки. Но библиотеки классов, кроме стандартной, не являются частью языка.

Разработчики Java включили в язык дополнительную конструкцию — паке-ты (packages). Все классы Java распределяются по пакетам. Кроме классов пакеты могут включать в себя интерфейсы и вложенные подпакеты (subpackages). Образуется древовидная структура пакетов и подпакедчэв.

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

Каждый пакет образует одно пространство имен (namespace). Это означает, что все имена классов, интерфейсов и подпакетов в пакете должны быть уникальны. Имена в разных пакетах могут совпадать, но это будут разные программные единицы. Таким образом, ни один класс, интерфейс или под-пакет не может оказаться сразу в двух пакетах. Если надо использовать два класса с одинаковыми именами из разных пакетов, то имя класса уточняется именем пакета: пакет.класс . Такое уточненное имя называется полным именем класса (fully qualified name).

Все эти правила, опять-таки, совпадают с правилами хранения файлов и подкаталогов в каталогах.

Пакетами пользуются еще и для того, чтобы добавить к уже имеющимся правам доступа к членам класса private, protected и public еще один, «пакетный» уровень доступа.

Если член класса не отмечен ни одним из модификаторов private, protected, public, то, по умолчанию, к нему осуществляется пакетный доступ (default access), а именно, к такому члену может обратиться любой метод любого класса из того же пакета. Пакеты ограничивают и доступ к классу целиком — если класс не помечен модификатором public , то все его члены, даже открытые, public , не будут видны из других пакетов.

Как же создать пакет и разместить в нем классы и подпакеты?

Пакет и подпакет

Чтобы создать пакет надо просто в первой строке Java-файла с исходным кодом записать строку package имя; , например:

Тем самым создается пакет с указанным именем mypack и все классы, записанные в этом файле, попадут в пакет mypack . Повторяя эту строку в начале каждого исходного файла, включаем в пакет новые классы.

Имя подпакета уточняется именем пакета. Чтобы создать подпакет с именем, например, subpack , следует в первой строке исходного файла написать;

и все классы этого файла и всех файлов с такой же первой строкой попадут в подпакет subpack пакета mypack .

Можно создать и подпакет подпакета, написав что-нибудь вроде

и т. д. сколько угодно раз.

Поскольку строка packageимя; только одна и это обязательно первая строка файла, каждый класс попадает только в один пакет или подпакет.

Компилятор Java может сам создать каталог с тем же именем mypack, a в нем подкаталог subpack, и разместить в них class-файлы с байт-кодами.

Полные имена классов А, в будут выглядеть так: mypack.A, mypack.subpack.в.

Фирма SUN рекомендует записывать имена пакетов строчными буквами, тогда они не будут совпадать с именами классов, которые, по соглашению, начинаются с прописной. Кроме того, фирма SUN советует использовать в качестве имени пакета или подпакета доменное имя своего сайта, записанное в обратном порядке, например:

До сих пор мы ни разу не создавали пакет. Куда же попадали наши файлы с откомпилированными классами?

Компилятор всегда создает для таких классов безымянный пакет (unnamed package), которому соответствует текущий каталог (current working directory)

файловой системы. Вот поэтому у нас class-файл всегда оказывался в том же каталоге, что и соответствующий Java-файл.

Безымянный пакет служит обычно хранилищем небольших пробных или промежуточных классов. Большие проекты лучше хранить в пакетах. Например, библиотека классов Java 2 API хранится в пакетах java, javax, org.omg. Пакет Java содержит только подпакеты applet, awt, beans, io, lang, math, net, rmi, security, sql, text, util и ни одного класса. Эти пакеты имеют свои подпакеты, например, пакет создания ГИП и графики java.awt содержит подпакеты color, datatransfer, dnd, event, font, geometry, im,image, print.

Конечно, состав пакетов меняется от версии к версии.

Пакеты

Классы в Java классы объединяются в пакеты, которые являются, своего рода логической структурой. Если сравнивать с реальным миром, то классы — это инструменты. А инструменты, как правило распределяют по их видам. Вот простой пример:

Cадовый инвентарь

Ручной и электроинструмент

Разумеется, в java уже включён свой набор встроенных пакетов. С некоторыми из них мы уже успели поработать: java.util, например. Пакет содержит набор классов, а каждый класс включает в себя определённое количество методов. Пример ниже демонстрирует пакет java.lang, и один из его классов Math, включающего набор математических методов:

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

Получается, что самая минимальная программа на java должна иметь класс, содержащий главный метод main. И этот класс обязательно должен принадлежать пакету. Во всех вновь созданных проектах на java пакет (package) автоматически создаётся средой разработки:

Архитектура: package -> class -> main:package first; public class Program < public static void main(String[] args) < System.out.println("Hello"); >>

Получается, что в составе проекта, нужно:

  • создать отдельную папку с именем пакета;
  • создать файл с именем класса и поместить в эту папку.

В случае с проектом выше среда разработки сама создала папку first, а в ней разместила файл с именем Program.java.

Имена пакетов записываются, как правило, с маленькой буквы. Для того, чтобы лучше понять принцип работы с пакетами создадим проект под названием, например, package_test:

При этом, обратите внимание, что при создании главного класса, ему было дано имя Program.

Когда мы работаем в среде программирования (NetBeans, например), то в левой части можем видеть навигатор, отражающий структуру проекта. Тут видно, что Program.java находится внутри пакета package_test.

Добавим новый пакет, который назовём foreaders (для читателей), в котором создадим класс Book. Для того, чтобы создать новый пакет необходимо правой кнопкой мыши кликнуть по элементу Source Packages и выбрать пункт контекстного меню «Java Package…«:

Среди пакетов теперь можно увидеть созданный foreaders. Теперь правой кнопкой мыши необходимо кликнуть на него и создать в нём новый класс Book:

«Наполним» созданный класс Book минимальным содержанием:

Пакет foreaders и его классpackage foreaders; public class Book < String name; //название книги String author; // автор книги < // инициализатор - книга по умолчанию name = "Thinking in Java"; author = "Bruce Eckel"; >// метод выводит информацию о книге public void aboutBook() < System.out.println(author + ", " + name); >> 

В методе main() класса Programm (пакет: package_test) вызовем класс Book (пакет: foreaders) и реализуем его:

Пакет package_test и класс Programm (метод: main)package package_test; // импорт класса Book из пакета foreaders import foreaders.Book; public class Program < public static void main(String[] args) < var book = new Book(); book.aboutBook(); >>Выведет: Bruce Eckel, Thinking in Java

Пакеты, встроенные в Java и их вызов

Ранее мы неоднократно использовали класс Scanner, который находится в пакете java.util. Его можно подключить уже известным способом, через import:

Подключение Scanner через importpackage package_test; import java.util.Scanner; public class Program < public static void main(String[] args) < Scanner in = new Scanner(System.in); >>

Директива import указывает на имя подключаемого класса (в данном случае класса Scanner).

В примерах выше подключался один класс: Book из созданного нами пакета, Scanner из вcтроенного пакета. Но встроенный пакет java.util содержит не только класс Scanner. Чтобы не подключать по отдельности каждый класс, можно сразу подключить все классы пакета (пакет целиком):

Подключение всех классов пакета java.utilimport java.util.*; // импорт всех классов из пакета java.util Теперь можно использовать любой класс из пакета java.util.

Также класс Scanner может быть подключён с использованием полного пути:

Подключение Scanner, используя полный путьpackage package_test; public class Program < public static void main(String[] args) < java.util.Scanner in = new java.util.Scanner(System.in); >>

Указание полного пути как раз и позволяет одновременно использовать классы с одинаковым именем, но принадлежащих разным пакетам. Например, класс Date имеется как в пакете java.util, так и в пакете java.sql:

Подключение без конфликта имёнjava.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date(); 

Статические члены класса будут рассмотрены позже. Пока достаточно сказать, что использование статического члена класса не требует создания объекта. Например класс Math содержит большое количество математических методов и все они статические. При подключении таких классов производится статический импорт. Вместе с директивой import используется модификатор static:

Вычисление косинуса углаpackage package_test; import static java.lang.System.*; import static java.lang.Math.*; public class Program < public static void main(String[] args) < double angle = 60; // угол в 60 градусов double radian = PI / 180 * angle; double result = cos(radian); out.printf("%.2f\n", result); >>

Статический импорт позволил использовать методы без названия класса. Например, писать не Math.cos(radian), а cos(radian), не Math.PI (число Пи), а просто PI. Благодаря статическому импорту System стала возможны запись: out.printf(«%.2f\n», result).

Классы из пакета java.lang (например, String) подключаются в программу автоматически. Их нет необходимости импортировать.

Можно подвести итог:

  • каждый проект на языке Java использует пакеты — отдельные модули (пространство имен), которым соответствует одноименный каталог (папка);
  • пакет содержит библиотеки (группы) классов;
  • количество классов в пакете неограниченно;
  • пакеты могут иметь разнообразные уровни вложения (подкаталоги, подпапки);
  • на разных уровнях вложения пакетов имена могут повторяться.

Что такое package (пакеты) в Java

Допустим, необходимо создать класс с именем Applet. Такая ситуация, конечно, большая редкость, но ситуации бывают разные… Однако этот класс уже есть в библиотеке Java. Чтобы использовать оба класса под тем же именем, нужно поместить их в разные пакеты, а затем импортировать (т.е. вставить в ваш файл определения классов) один из них. Пакетом, таким образом, называется объединение классов.

Создать пакет очень просто: нужно в файл перед определением классов вставить следующую строку:

package ИмяПакета;

Пакеты должны располагаться в соответствующих директориях, т.е. файл пакета (с именем ИмяПакета) должен быть сохранен в папке ИмяПакета.
Пакеты могут быть вложенными (например, java.util, где java— главный пакет, autil — вложенный). Соответственно эти два пакета должны располагаться в каталоге j ava\util.
Создадим для примера пакет (листинг 6.1).

Листинг 6.1.
Пример создания пакета из двух классов

Мы создали пакет из двух классов.
Уровни доступа в пакетах такие:
1. Public — члены класса доступны из всех пакетов.
2. Protected— члены класса доступны всем подклассам и неподклассам из того же пакета.
3. Без модификатора — члены класса доступны только в этом пакете.
4. Private — члены класса доступны только в том же классе.
У классов могут быть два уровня доступа:
• public — класс доступен отовсюду;
• без модификатора — класс доступен только в этом пакете.
Чтобы использовать пакет, необходимо подключить его к коду (импортировать). Это делается следующим образом.

import ИмяПакета.ИмяКласса; import ИмяПакета.*;

В первом случае мы импортируем только один класс, а во втором — импортируем полный пакет. Предположим, нам нужно создать две переменные классов Date и Calendar. Вот как это будет выглядеть, если мы не импортируем пакет (листинг 6.2).

Листинг 6.2.
Создание двух переменных классов Date и Calendar

Теперь импортируем пакет java.util.

Листинг 6.3.
Импорт пакета java.util

Согласитесь, второй вариант короче. Теперь импортируем наш пакет fruits в программу (листинг 6.4).

Листинг 6.4.
Импорт пакета fruits в программу

Легко заметить, что работа с пакетами очень проста. Рассмотрим теперь стандартные пакеты языка Java.

Вам також може сподобатися

Start Android gamedev |

Инструменты android разработчика 3 2 195
Хотите научиться создавать игры для android? Наши уроки по разработке игр помогут вам научится

Kotlin Coroutines

Архитектура андроид-приложений 1 14 202
В третьей части этой серии вы узнали, как тестировать корутины через поведение. В этой

Android Studio Tutorial - Clipboard (работа с буфером обмена)

Уроки по android разработке на Java 0 1 403

[:ru]В этом уроке о том, как вывести список всех музыкальных файлов в памяти устройства. С получением

Тесты к урокам StartAndroid (разработка под андроид)

Уроки по android разработке на Java 0 234
Вернуться к уроку 11 Перейти к уроку 12 [mlw_quizmaster

Android Studio Tutorial - Clipboard (работа с буфером обмена)

Уроки по android разработке на Java 0 1 611
Урок о том, как в TextView применить тень для текста.

Бесплатный курс Python

Новости 1 2 683

Python – один из самых популярных языков программирования. Программы, написанные на нем, могут работать

Коментарі: 1
Додати коментар Скасувати відповідь

Щоб відправити коментар вам необхідно авторизуватись.

Пакеты, системы, модули, библиотеки — КАКОГО?

По моим наблюдениям, минимум раз в неделю в списке c.l.l или другом Lisp-списке «новички» путаются в том, что связано с пакетами. Говорят о «загрузке» пакета, «требовании» (requiring) пакета, удивляются тому, что после загрузки системы нужно пользоваться маркерами пакетов и т.д. Меня это раздражает, думаю также, что это может быть одной из причин, почему начинающие считают, что использование библиотек в Lisp сложнее, чем есть на самом деле.

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

Прежде всего следует иметь ясную голову. Термин «пакет» сильно перегружен. В дистрибутивах Linux вроде Debian или Gentoo есть «пакеты», «пакеты» есть в языках программирования Java, Perl или Python. Вполне вероятно, что вы пришли в Lisp с предвзятым мнением относительно того, что такое «пакет» или чем он должен быть.

Пакеты

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

В Common Lisp есть функции и макросы для создания, изменения, исследования и удаления пакетов. Очень хорошее введение в пакеты (и символы) можно найти в главе 21 великолепной книги Practical Common Lisp Питера Сайбела. Определение термина находится в главе 11 (онлайн-версии) стандарта ANSI Common Lisp specification.

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

Кроме того, если ваш Lisp жалуется, что не может найти какой-то пакет, это означает, что пакета как Lisp-объекта нет в образе (т.е. FIND-PACKAGE возвращает NIL ), потому что его еще никто не создал. Это не означает, что Lisp-машина поискала в файловой системе и ничего не нашла. (Частая причина такой неудачи состоит в том, что события происходят в неправильном порядке. Об этом ниже.)

Системы

Системы, в отличие от пакетов, даже не упоминаются в стандарте. Тем не менее, опытные Lisp-программисты знают этот термин, поскольку им потребуютется знать и применять какой-то инструмент определения систем. Наиболее заметный сегодня — ASDF (используется большинством Lisp-библиотек с открытым исходным кодом); другой известный инструмент определения систем, гораздо старше ASDF — MK:DEFSYSTEM. Некоторые разработчики также поставляют свои инструменты определения систем вместе с дистрибутивами, см. например, Common Defsystem для LispWorks.

В этом ключе система, строго говоря, это набор кода плюс инструкция по его обработке, например, зависимости от других систем, что следует загрузить/скомпилировать в первую очередь и т.д. Другими словами, инструмент определения систем по своему назначению похож на make или Ant.

Кроме того, инструмент определения систем обычно может намного больше — Common Defsystem может, например, интегрировать файлы библиотек типов COM, ASDF полностью расширяем и использовался, среди прочего, для компиляции файлов на C. Он также часто используется для определения тестовых наборов описываемой системы.

Хотя ASDF и весьма популярен, он не вездесущ. Он идет предустановленным со многими Lisp-системами вроде SBCL, OpenMCL или AllegroCL, вероятнее всего, что он загрузится и в других Lisp-системах, но этот факт не делает его частью Common Lisp. Это набор кода без явной спецификации и с разными версиями, которые бывают несовместимы между собой.
Поди пойми…

Модули

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

Например, в LispWorks можно использовать

(require "foreign-parser") 

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

(require :asdf) 

для загрузки ASDF на OpenMCL, но не в LispWorks.

Некоторые дистрибутивы предлагают хуки для настройки работы REQUIRE , и существуют расширения вроде common-lisp-controller, соединяющие REQUIRE с ASDF, однако в общем случае модуль — это такая штуковина, которая зависит от реализации и которую не следует путать с системами (ASDF), и, тем более, с пакетами.

Библиотеки

Скорее всего вы не найдете четкого определения, что такое библиотека. Большинство людей думают об этом как о коллекции кода, предназначенного для выполнения одной или нескольких определенных задач и распространяемого как единое целое, обычно в виде сжатого архива, который можно откуда-то скачать. На самом деле, это неясное определение является, думаю, наиболее подходящим при разговоре о программах, написанных на Lisp. Большинство Lisp-библиотек сегодня включают в себя определение (ASDF) системы, но это вовсе не обязательно. Возможно, в зависимости от способа получения, это будет модуль в вашей Lisp-системе, но и это тоже не обязательно. Кроме того, библиотека обычно определяет один или несколько пакетов, а может и не определять ни одного.

И, по соглашению, а может из-за недостатка фантазии, может сложится и часто складывается ситуация, когда библиотека «Ку» идет с определением системы «Ку», которую можно загрузить как модуль «Ку». После загрузки кода получите новый пакет, называемый «Ку». Четыре разных сущности с одинаковым именем! Я допускаю, что это сбивает с толку, но надеюсь, что несколько предыдущих абзацев помогли слегка прояснить ситуацию.

Но у меня все еще ничего не работает!

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

;; в этой строчка также может быть написано (require :cl-ppcre) (asdf:oos 'asdf:load-op :cl-ppcre) (defun my-simple-number-scanner (string) (cl-ppcre:scan "^[0-9]+$" string)) 

Почему так? Почему я могу загрузить этот файл, но не могу скомпилировать его? И почему я могу скомпилировать его после загрузки? Не странно ли?

Нет, не странно. Компилятор читает первую форму (которая является инструкцией скомпилировать — если необходимо — и загрузить систему CL-PPCRE, но не выполнить ее. В конце концов, компилятор заинтересован лишь в компиляции кода. После выполнения первой формы он переходит ко второй форме, к определению функции. Здесь возможно сообщение об ошибке, так как Lisp-сканер, пытающийся читать эту форму, обнаружит последовательность символов «cl-ppcre:scan», которая должна обозначать внешний символ из пакета CL-PPCRE, но самого пакета CL-PPCRE еще нет. В процессе загрузки системы CL-PPCRE, кроме всего прочего, создается пакет CL-PPCRE, но этого еще не произошло. Читайте главу 3 CLHS.

Можно воспользоваться EVAL-WHEN для указания компилятору загрузить CL-PPCRE перед чтением второй формы. Следует, однако, найти другой способ организации своего кода. Первая форма — это просто обявление того, что ваш код зависит от системы CL-PPCRE. Такое не должно находиться в том же файле, что и Lisp-код. Напишите определение системы для вашей программы и поместите зависимости туда.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *