Что такое пакет в программировании
Перейти к содержимому

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

  • автор:

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

Кресла офисные 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.

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

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

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

Пакетные менеджеры выглядят сложновато со стороны, но когда раскуришь их, становится понятно, легко и интересно. Расскажем обо всём этом сегодня.

Что такое пакет и чем он отличается от обычной программы

Пакет — это специальный набор файлов и данных. В пакете содержится:

  • сама программа, которую нужно установить;
  • файлы с настройкой — куда что копировать;
  • информация о том, какие ещё пакеты или библиотеки нужны для установки;
  • команды и другие действия, которые нужно будет выполнить во время установки;
  • сведения о версии программы.

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

Зависимости и менеджер пакетов

Кроме установки, у менеджера пакетов много работы, но основная — распутать все зависимости. Зависимость пакетов — это когда для работы одного пакета требуется установка нескольких других, причём определённых версий.

Допустим, менеджер пакетов ставит пакет «Волшебный веб-сайт за 10 минут», смотрит его зависимости и понимает, что для работы ему нужны:

  • база данных MySQL 7-й версии;
  • утилита ssh любой версии;
  • веб-сервер Apache версии 2.4.0 или позднее.

Менеджер пакетов смотрит в список уже установленных программ и видит, что ssh уже стоит, Apache есть версии 2.4.2, а MySQL вообще не установлена. Это значит, что он первую установку ставит на паузу и начинает качать и устанавливать пакет с MySQL 7-й версии. С ним повторяется то же самое — менеджер смотрит, какие пакеты указаны в зависимостях, качает их и ставит. Как только всё установлено — возвращается к первоначальной задаче и ставит пакет «Волшебный веб-сайт за 10 минут».

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

Удаление пакетов

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

Что такое репозиторий

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

Обычно у каждого семейства операционных систем свой репозиторий и свой менеджер пакетов, который с ним работает. Например:

  • dpkg — менеджер пакетов для Debian. В репозитории Debian огромное количество пакетов — он работает с 1994 года.
  • rpm — менеджер пакетов для RedHat Linux.
  • portage — менеджер для Gentoo. Его особенность в том, что все программы компилируются при установке под то железо и процессор, который установлен в системе. Это даёт прирост производительности, но усложняет установку программ.

Почти все менеджеры пакетов работают из командной строки — это стандарт в Linux- и UNIX-системах. Например, команда rpm MySQL-server-standard-5.0.24-0.rhel4.i386.rpm установит MySQL в Red Hat Linux, а команда emerge —ask dev-db/phpmyadmin скачает исходные файлы панели управления базы данных и скомпилирует их в Gentoo Linux:

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

Менеджеры пакетов в программировании

На самом деле мы уже пользовались менеджерами пакетов, когда делали свои проекты:

  • Запускаем нейросеть на домашнем компьютере
  • Моделируем игру в рулетку на Python
  • Телеграм-бот на Python

Здесь мы использовали pip — менеджер пакетов для Python. С его помощью мы устанавливали все необходимые библиотеки, без которых приложение бы не работало. Например, вот что можно сделать с pip:

pip install plotly — установить библиотеку plotly, чтобы мы могли рисовать графики

pip check pandas — проверить зависимости у выбранного пакета

pip uninstall telebot — удалить библиотеку для работы с телеграм-ботом

А для проекта с тепловыми картами твитов Байдена и Трампа нам нужны были три библиотеки, и мы использовали команду pip list, чтобы посмотреть, есть они у нас или нет.

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

А в проекте с менеджером паролей мы вовсю использовали npm — менеджер пакетов Node.js: с его помощью мы установили Электрон и превратили веб-проект в отдельное приложение:

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

Вот ещё несколько команд npm:

npm update -g npm — обновить сам менеджер пакетов

npm install mysql — установить базу данных MySQL

npm install-test — установить пакет и проверить тестами его работу

Бытовые менеджеры

В каком-то смысле магазины приложений типа AppStore и RuStore — это тоже менеджеры пакетов:

  • Программы хранятся централизованно на каких-то серверах и представлены в каталоге.
  • Установкой и обновлением приложений занимается сам магазин приложений.
  • Если приложению что-то нужно, магазин сам проверит наличие этого и установит при необходимости.

Вместе с тем на Android и Mac OS можно установить приложения в обход сторов. Кому что удобнее.

Когда менеджера пакетов нет

В Windows каждое приложение отвечает само за себя: если нужно что-то установить, обновить или удалить, вы просто это делаете. С одной стороны, это удобно, а с другой не очень:

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

Жить с этим можно, но это не лучший вариант.

Что дальше

Чтобы было интереснее, мы установим Linux в виртуальную машину и поэкспериментируем с менеджером пакетов — посмотрим, что он умеет, чем полезен и как с ним работать.

Читаете «Код»? Зарабатывайте на коде

Сфера ИТ и разработки постоянно растёт и требует новых кадров. Компании готовы щедро платить даже начинающим разработчикам, а опытных вообще отрывают с руками. Обучиться на разработчика можно в «Яндекс Практикуме».

Читаете «Код»? Зарабатывайте на коде Читаете «Код»? Зарабатывайте на коде Читаете «Код»? Зарабатывайте на коде Читаете «Код»? Зарабатывайте на коде

Получите ИТ-профессию

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

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

Хотя корни Ады лежат в языке Паскаль, концепция пакетов была заимствована из других языков программирования и подверглась значительному влиянию последних наработок в области разработки программного обеспечения обсуждавшихся в 1970-х годах. Несомненно, что одной из главных инноваций в этот период была концепция программного модуля (или пакета).

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

7.1 Общие сведения о пакетах Ады

7.1.1 Идеология концепции пакетов

    Примечание:
    В системе компилятора GNAT существует соглашение согласно которому файлы спецификаций имеют расширение ads (ADa Specification), а файлы тел имеют расширение adb (ADa Body).

7.1.2 Спецификация пакета

Как уже говорилось, спецификация пакета Ады определяет интерфейс доступа к вычислительным ресурсам (сервисам) пакета. Она может содержать описания типов, переменных, констант, спецификации подпрограмм, других пакетов, — все то, что должно быть доступно тому, кто будет использовать данный пакет. Простой пример спецификации пакета может иметь следующий вид:

 package Odd_Demo is type A_String is array (Positive range <>) of Character; Pi : constant Float := 3.14; X : Integer; type A_Record is record Left : Boolean; Right : Boolean; end record; -- примечательно, что дальше, для двух подпрограмм представлены только -- их спецификации, тела этих подпрограмм будут находиться в теле пакета procedure Insert(Item : in Integer; Success : out Boolean); function Is_Present(Item : in Integer) return Boolean; end Odd_Demo; 

Мы можем получить доступ к этим сервисам в нашем коде путем указания данного пакета в спецификаторе совместности контекста with, а затем использовать полную точечную нотацию. Полная точечная нотация, в общем случае, имеет следующий вид:

 имя_пакета.имя_используемого_ресурса 

где имя_используемого_ресурса — это имя типа, подпрограммы, переменной и т.д.

Для демонстрации сказанного приведем схематический пример процедуры которая использует показанную выше спецификацию:

 with Odd_Demo; procedure Odder_Demo is My_Name : Odd_Demo.A_String; Radius : Float; Success : Boolean; begin Radius := 3.0 * Odd_Demo.Pi; Odd_Demo.Insert(4, Success); if Odd_Demo.Is_Present(34) then . . . . end Odder_Demo; 

Не трудно заметить, что доступ к ресурсам пакета, текстуально подобен доступу к полям записи.

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

 with Odd_Demo; use Odd_Demo; procedure Odder_Demo is My_Name : A_String; Radius : Float; Success : Boolean; begin Radius := 3.0 * Pi; Insert(4, Success); if Is_Present(34) then . . . . end Odder_Demo; 

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

 ------------------------------- package No1 is A, B, C : Integer; end No1; ------------------------------- package No2 is C, D, E : Integer; end No2; ------------------------------- with No1; use No1; with No2; use No2; procedure Clash_Demo is begin A := 1; B := 2; C := 3; -- двусмысленность, мы ссылаемся -- на No1.c или на No2.c? No1.C := 3; -- избавление от двусмысленности путем возврата No2.C := 3; -- к полной точечной нотации end Clash_Demo; 

Может возникнуть другая проблема — когда локально определенный ресурс «затеняет» ресурс пакета указанного в инструкции use. В этом случае также можно избавиться от двусмысленности путем использования полной точечной нотации.

 package No1 is A : Integer; end No1; with No1; use No1; procedure P is A : Integer; begin A := 4; -- это - двусмысленно P.A := 4; -- удаление двусмысленности путем указания -- имени процедуры в точечной нотации No1.A := 5; -- точечная нотация для пакета end P; 
7.1.3 Тело пакета

Тело пакета содержит все детали реализации сервисов, указаных в спецификации пакета. Схематическим примером тела пакета, для показанной выше спецификации, может служить:

 package body Odd_Demo is type List is array (1..10) of Integer; Storage_List : List; Upto : Integer; procedure Insert(Item : in Integer; Success : out Boolean) is begin . . . end Insert; function Is_Present(Item : in Integer) return Boolean is begin . . . end Is_Present; begin -- действия по инициализации пакета -- это выполняется до запуска основной программы! for I in Storage_List'Range loop Storage_List(I) := 0; end loop; Upto := 0; end Odd_Demo; 

Все ресурсы, указанные в спецификации пакета, будут непосредственно доступны в теле пакета без использования дополнительных инструкций спецификации контекста with и/или use.

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

Переменные, описанные в теле пакета, сохраняют свои значения между успешными вызовами публично доступных подпрограмм пакета. Таким образом, мы можем создавать пакеты, которые сохраняют информацию для более позднего использования (другими словами: сохранять информацию о состоянии).

Раздел «begin . end«, в конце тела пакета, содержит перечень инструкций инициализации для этого пакета. Инициализация пакета выполняется до запуска на выполнение главной подпрограммы. Это справедливо для всех пакетов. Следует заметить, что стандарт не определяет порядок выполнения инициализации различных пакетов.

7.2 Средства сокрытия деталей реализации внутреннего представления данных

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

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

Ада позволяет «закрыть» детали внутреннего представления данных и, таким образом, избавиться от проблемы массовых переделок. Такие возможности обеспечивает использование приватных типов (private types) и лимитированных приватных типов (limited private types).

7.2.1 Приватные типы (private types)

    — изъятие средств (Withdraw)
    — размещение средств (Deposit)
    — создание счета (Create)
 package Accounts is type Account is private; -- описание будет представлено позже procedure Withdraw(An_Account : in out Account; Amount : in Money); procedure Deposit( An_Account : in out Account; Amount : in Money); function Create( Initial_Balance : Money) return Account; function Balance( An_Account : in Account) return Integer; private -- эта часть спецификации пакета -- содержит полные описания type Account is record Account_No : Positive; Balance : Integer; end record; end Accounts; 
    — присваивание
    — проверка на равенство (не равенство)
    — проверки принадлежности («in«, «not in«)
 with Accounts; use Accounts; procedure Demo_Accounts is Home_Account : Account; Mortgage : Account; This_Account : Account; begin Mortgage := Accounts.Create(Initial_Balance => 500.00); Withdraw(Home_Account, 50); . . . This_Account := Mortgage; -- присваивание приватного типа - разрешено -- сравнение приватных типов if This_Account = Home_Account then . . . end Demo_Accounts; 

7.2.2 Лимитированные приватные типы (limited private types)

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

В качестве демонстрации сказанного, рассмотрим следующий пример:

 package Compare_Demo is type Our_Text is private; . . . private type Our_Text (Maximum_Length : Positive := 20) is record Length : Index := 0; Value : String(1..Maximum_Length); end record; . . . end Compare_Demo; 

Здесь, тип Our_Text описан как приватный и представляет из себя запись. В данной записи, поле длины Length определяет число символов которое содержит поле Value (другими словами — число символов которые имеют смысл). Любые символы, находящиеся в позиции от Length + 1 до Maximum_Length будут нами игнорироваться при использовании этой записи. Однако, если мы попросим компьютер сравнить две записи этого типа, то он, в отличие от нас, не знает предназначения поля Length. В результате, он будет последовательно сравнивать значения поля Length и значения всех остальных полей записи. Очевидно, что алгоритм предопределенной операции сравнения в данной ситуации не приемлем, и нам необходимо написать собственную функцию сравнения.

Для подобных случаев Ада предусматривает лимитированные приватные типы. Изменим рассмотренный выше пример следующим образом:

    . . . procedure Init (T : in out Our_Text; S : in String); . . .

Напомним, что спецификация такой процедуры должна быть размещена в спецификации пакета Compare_Demo, а ее тело (реализация) — в теле этого пакета.

7.2.3 Отложенные константы (deferred constants)

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

 package Coords is type Coord is private; Home: constant Coord; -- отложенная константа! private type Coord is record X : Integer; Y : Integer; end record; Home : constant Coord := (0, 0); end Coords; 

В результате такого описания, пользователи пакета Coords «видят» константу Home, которая имеет приватный тип Coord, и могут использовать эту константу в своем коде. При этом, детали внутреннего представления этой константы им не доступны и они могут о них не заботиться.

7.3 Дочерние модули (child units) (Ada95)

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

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

Дочерние модули непосредственно используются в стандартной библиотеке Ады. В частности, дочерними модулями являются такие пакеты как Ada.Text_IO, Ada.Integer_Text_IO. Следует также заметить, что концепция дочерних модулей была введена стандартом Ada95. В стандарте Ada83 эта идея отсутствует.

7.3.1 Расширение существующего пакета

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

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

 package Stacks is type Stack is private; procedure Push(Onto : in out Stack; Item : Integer); procedure Pop(From : in out Stack; Item : out Integer); function Full(Item : Stack) return Boolean; function Empty(Item : Stack) return Boolean; private -- скрытая реализация стека . -- точка  A  end Stacks; package Stacks.More_Stuff is function Peek(Item : Stack) return Integer; end Stacks.More_Stuff; 

    Примечание:
    Согласно правил именования файлов, принятым в системе компилятора GNAT, спецификация и тело пакета Stacks должны быть помещены в файлы:

      stacks.adsи stacks.adb
      stacks-more_stuff.adsи stacks-more_stuff.adb
     with Stacks.More_Stuff; procedure Demo is X : Stacks.Stack; begin Stacks.Push(X, 5); if Stacks.More_Stuff.Peek = 5 then . . . end Demo; 

    Следует заметить, что включение дочернего пакета в инструкцию спецификатора совместности контекста with автоматически подразумевает включение в инструкцию with всех пакетов-родителей. Однако, инструкция спецификатора использования контекста use таким образом не работает. То есть, область видимости может быть получена пакетом только в базисе пакета.

     with Stacks.More_Stuff; use Stacks; use More_Stuff; procedure Demo is X : Stack; begin Push(X, 5); if Peek(x) = 5 then . . . end Demo; 

    Необходимо также заметить, что подпрограммы (процедуры и функции) могут быть дочерними модулями пакета (правила их использования достаточно очевидны). При этом, однако, сами подпрограммы не могут иметь дочерние модули.

    7.3.2 Иерархия модулей как подсистема

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

    В подобных ситуациях, используя концепцию дочерних модулей Ады, можно выделить каждую отдельно разрабатываемую подсистему в самостоятельную иерархию модулей. При этом, каждая подсистема будет иметь свой собственный корневой пакет с уникальным именем.

     package Root is -- корневой пакет может быть пустым end Root; 

    Поскольку имя корневого пакета уникально, то имена дочерних модулей иерархии также будут уникальны, что, в результате, минимизирует вероятность коллизии имен. Кроме того, такой прием является удобным средством разделения большого проекта на логически самостоятельные составные части.

    Примером использования подобного подхода может служить стандартная библиотека Ады, которая предстявляется как набор дочерних модулей трех корневых пакетов: Ada, Interfaces и System.

    7.3.3 Приватные дочерние модули (private child units)

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

    В спецификацию приватных дочерних пакетов разрешается включать приватную часть спецификации их пакетов-родителей, поскольку такие дочерние модули — приватны. В обычном случае — это не разрешается, так как нарушает сокрытие деталей реализации родительской приватной части.

     private package Stacks.Statistics is procedure Increment_Push_Count; end Stacks.Statistics; 

    Процедура Stacks.Statistics.Increment_Push_Count могла бы быть вызвана внутри реализации пакета Stacks. Такая процедура не будет доступна ни одному внешнему, по отношению к этой иерархии модулей, клиенту.

    Copyright (C) А.Гавва V-0.4w май 2004

    Что такое 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.

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

    Android Design Support Library - поддержка компонентов Material Design в приложениях с Android 2.1 до Android 5+ (с примерами)

    Дизайн android приложений 6 8 882
    Android 5.0 Lollipop – один из самых значимых релизов системы Android , в немалой степени

    Урок 23. Жизненный цикл активити (Activity Lifecycle) | Уроки Android Studio

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

    В этом уроке узнаем, что такое Activity Lifecycle, познакомимся с методами жизненного цикла активити,

    Start Android gamedev |

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

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

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

    [:ru]Обратное геокодирование – это процесс преобразования географических координат в читабельный адрес. Исходный код.[:en]Reverse geocoding

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

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