Как объединить классы в java

от admin

Как объединить классы в java

Как правило, в Java классы объединяются в пакеты. Пакеты позволяют организовать классы логически в наборы. По умолчанию java уже имеет ряд встроенных пакетов, например, java.lang , java.util , java.io и т.д. Кроме того, пакеты могут иметь вложенные пакеты.

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

Чтобы указать, что класс принадлежит определенному пакету, надо использовать директиву package , после которой указывается имя пакета:

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

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

Например, создадим в папке для исходных файлов каталог study . В нем создадим файл Program.java со следующим кодом:

Директива package study в начале файла указывает, что классы Program и Person, которые здесь определены, принадлежат пакету study.

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

Для компиляции программы вначале в командной строке/терминале с помощью команды cd перейдем к папке, где находится каталог study.

Например, в моем случае это каталог C:\java (то есть файл с исходным кодом расположен по пути C:\java\study\Program.java).

Для компиляции выполним команду

После этого в папке study появятся скомпилированные файлы Program.class и Person.class. Для запуска программы выполним команду:

Компиляция пакетов в Java

Импорт пакетов и классов

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

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

То есть мы указываем полный путь к файлу в пакете при создании его объекта. Однако такое нагромождение имен пакетов не всегда удобно, и в качестве альтернативы мы можем импортировать пакеты и классы в проект с помощью директивы import , которая указывается после директивы package:

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

В примере выше мы подключили только один класс, однако пакет java.util содержит еще множество классов. И чтобы не подключать по отдельности каждый класс, мы можем сразу подключить весь пакет:

Теперь мы можем использовать любой класс из пакета java.util.

Возможна ситуация, когда мы используем два класса с одним и тем же названием из двух разных пакетов, например, класс Date имеется и в пакете java.util , и в пакете java.sql . И если нам надо одновременно использовать два этих класса, то необходимо указывать полный путь к этим классам в пакете:

Статический импорт

В java есть также особая форма импорта — статический импорт. Для этого вместе с директивой import используется модификатор static :

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

То же самое в отношении класса System: в нем определен статический объект out , поэтому мы можем его использовать без указания класса.

Познаём Java. Вторая чашка: собираем классы в кучки. Пробуем апплеты

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

Как происходит загрузка классов?

Для того, чтобы найти класс по имени когда вы его вызываете, в Java существует стандартный загрузчик классов. Он оперирует понятием classpath. Список classpath — это набор путей, где следует искать файлы классов. Каждый classpath может указывать как на директорию, так и на так называемый jar-файл (зазипованная директория со скомпилированными .class’ами и разрешением .jar, типа «йА java-archive!»). По умолчанию в classpath входят файлы стандартных библиотек и директория, из которой вы вызвали саму Java. Именно таким образом был найден класс HelloWorld — java нашла файл HelloWorld.class и запустила в нём метод main. Собственно, так и работают большинство программ, даже самых сложных. Всё начинается с одного main’а…

Пакеты классов

Пакет (package) представляют собой набор классов, объединённых по смыслу. Пакеты обычно вкладываются друг в друга, образуя собо иерархию, дающую понять, что зачем. На файловой системе такая иерархия выглядит в виде вложенных друг в друга директорий с исходниками. Так, исходники пакета a лежат в папке a, исходники пакета a.b — в папке a/b и так далее. Типичный путь к пакету выглядит примерно так:
org.apache.commons.collectons . Видите, сразу ясно зачем он нужен. Чтобы использовать какой-то класс в коде другого класса, вы должны импортировать его, написав до объявления класса строку
import путь.к.классу.ИмяКласса;
Кроме того, если вы используете классы одного пакета часто, вы можете импортировать весь пакет:
import путь.к.классу.*;
Это относится ко всем пакетам, кроме java.lang — он импортирован по умолчанию, именно из него были в прошлом примере взяты классы System и String. На самом деле они лежат в некоем jar’е, в каталоге java/lang.

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

Организация кода

Если вы пишете свои первые маленькие примерчики и вам лень создавать иерархию классов — пусть, это ваше право. Но помните, в серьёзном проекте вы всегда должны будете разложить свои классы по пакетам. Обычно корневые пакеты создаются такими, чтобы ясно давать понять кто автор кода, и к чему он относится.
Например:
ru.vasiapupkin.photomaker выбирается корневым пакетом
ru.vasiapupkin.photomaker.core сюда мы пишем классы отвечающие за логику
ru.vasiapupkin.photomaker.visual сюда, допустим, все наши окошки приложения

и так далее.
Чтобы создать класс
ru.vasiapupkin.photomaker.Starter
вы должны:
создать файл Starter.java в папке ru/vasiapupkin/photomaker/
прописать в нём первой строчкой (точнее говоря, до импортов)
package ru.vasiapupkin.photomaker;

Коллижн

«А что будет, если у нас будет два класса с одним именем?», — спросите вы. «Смотрите», — отвечу я.
Допустим вы решили что вы умнее джавы и создали свой класс строки — String. Но вот проблема, у нас же уже есть такой!
Значит, вам придётся положить свой класс в пакет, скажем ru.vp.stuff и обращаться к нему так: ru.vp.stuff.String.
Именно поэтому не рекомендуется класть классы прямо в корень classpath — таким образом вы роете себе дорогу к несовместимости, ведь Java требует, чтобы каждый класс определялся однозначно. Именно поэтому нельзя написать так:
import ru.vp.SuperClass;
import ru.mashka.SuperClass;
За это вас накажет компилятор, потому что он не будет знать, какой из них использовать.
Мораль: правильно выбирайте и имя класс и имя пакета.

Погоняем?

Давайте улучшим первое приложение. Эх, классика интернета… Создадим апплет.

Эх, может быть апплетами.

import java.applet.Applet ;
import java.awt.Graphics ;

public class HelloWorld extends Applet<

public void paint( Graphics g) <
g.drawString( «Hello World» ,15,15);
>

>

* This source code was highlighted with Source Code Highlighter .

Так, что у нас тут? Импортировано 2 класса, один из них — стандартный пустой апплет, который мы будем расширять. Второй — Graphics. Graphics — это понятие из библиотеки AWT. Кстати, небольшой экскурс. AWT (Abstract Window Toolkit) входил ещё в первую Java и был предназначен для многих задач, связанных в основном с отображением.
Так вот, объект типа Graphics позволяет нам рисовать на себе всякую муру типа строк, линий, кружочков и прочего. В данном примере мы написали строчку с отступом.
Метод paint здесь написан не от балды — он перекрывает аналогичный метод класса Applet, и когда java будет перерисовывать этот конкретный апплет, она вызовет этот метод.

Посмотреть на наш апплет достаточно просто — пишем небольшой HTML:

… а может приложением.

Давайте попробуем сделать HelloWorld в standalone-приложении.

import java.awt.* ;
import javax.swing.* ;
public class HelloWorld extends JFrame<

public static void main( String [] args) <
new HelloWorld();
>

<
add( new JLabel( «Hello world» ));
setSize(200,200);
setVisible( true );
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
>
>

* This source code was highlighted with Source Code Highlighter .

Здесь мы полностью импортируем основные классы пакетов Swing и AWT. Swing — более поздняя чем AWT библиотека, сейчас именно она обеспечивает отображение основной части графического интерфейса для Java-приложений.
Итак, в main мы просто создаём экземпляр класса HelloWorld.
Сейчас наш класс наследуется от класса JFrame. Это класс из Swing, он представляет собой окно, которое отображается пока не будет закрыто.
Блок <. >— это «общий конструктор». Он добавляется к любому конструктору нашего класса. Так как у нас нет ни одного — он добавляется к пустому конструктору без параметров, который создаётся на лету, если у класса нет ни одного.
Мы добавляем на окно новый объект типа JLabel (т.е. надпись), затем устанавливаем окну размеры и отображаем его. Последняя строчка нужна, чтобы выполнение приложения закончилось, когда будет закрыто окно. Таким образом, вы можете быть уверены что после закрытия окна у вас в памяти не останется висеть ваше приложение.
Запускать его нужно точно так же как и прошлое: пишем, компилируем, запускаем.

А может и сервлетами? Наверное, потом.

В этих двух статьях я постарался дать вам начальное представление о возможностях Java в общем. За рамками сегодняшней статьи (наверное, будут в завтрашней) остались сервлеты и прочие радости серверной части типа JSP-страниц, а также МИДлеты — приложения для мобилок. Я бы мог рассмотреть и то и то, но хотел бы знать, чего больше хотят читатели. Кроме того, возможно, нужно рассказать о самых основах языка. Примерно на том же уровне подробности, что и начало этой статьи. Напишите в комментариях, какую статью вы хотели бы видеть в следующий раз:
— классы и интерфейсы: ООП в джаве;
— буквы-цифры-строчки: работа с базовыми типами;
— создание оконных приложений с помощью Swing;
— от мала до велика: сервлеты, мидлеты и 2 слова о портлетах.

Когда отпишетесь — станет ясно, куда копать дальше. Всем спасибо за внимание.

Как объединить классы в java? Как с этих кусков кода сделать один проект?

Знаете кого-то, кто может ответить? Поделитесь ссылкой на этот вопрос по почте, через Твиттер или Facebook.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.3.11.43304

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Модуль 2. Урок 4. Пакеты в Java. — Введение в Java

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

Читать:
Как откатить биос на ноутбуке lenovo

Что такое пакеты?

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

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

Как аналогию, можно привести пример с адресами.

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

Что такое пакет для класса

Для класса его пакет — это его местоположение в проекте, относительно других классов. Благодаря разделению классов на несколько пакетов — мы организовываем структуру программы.

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

  • отсутствие модификатора перед методом или полем (еще говорят package-private) — означает, что данный член класса будет виден другим классам, но только из этого же пакета;
  • protected перед методом или полем — означает, что данный член класса будет виден не только классам текущего пакета, как с package-private, но и классам-наследникам.

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

По сути нам нужно:

  • создать текстовый файл с расширением .java в нужной папке;
  • в самом файле, помимо класса, написать имя его пакета.

Рассмотрим этот процесс поэтапно.

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

Или с помощью sublime:

Если команда subl не найдена и Вы уверены в том, что sublime установлен — проверьте, в переменных среды окружения, наличие прописанного пути к папке, в которой лежит subl.

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

Файл создан. Но класса в нем нет. Создадим класс:

Теперь у нас есть и файл в нужной папке, и класс в файле. Но сам класс ничего не знает про то, что он принадлежит некому пакету. Исправим это:

Не забываем сохранять файл!

Ключевые моменты верного создания класса внутри пакета:

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

Корень пакетов

А как же задать корневой каталог (папку) как основу пакетов, в котором уже и происходит ветвление этих всех под-пакетов (под-папок)? Почему, например, папка io является корнем для классов проекта, а папка src — не является пакетом, да и вообще не входит в пакетную структуру проекта?

Все очень просто: корневым пакетом считается тот который первым прописан в каждом java-файле после слова package , в текущем проекте. А в самом проекте помимо папки src, на ее уровне и выше, — могут быть много различных папок и файлов, для работы с проектом в целом. Но это не делает их корневым пакетом, или вообще частью пакетов java, в этом проекте, если они не включены в имена пакетов в классах, после ключевого слова package . Пример структуры папок и пакетов:

Пример содержимого класса OneMoreClass.java :

Пример содержимого класса SomeView.java :

Как видно из примеров выше — любой класс в этом проекте всегда содержит в имени пакета на первом месте папку io. Это и будет корневым пакетом проекта. На месте папки io могла быть папка com или любое другое имя. Важно чтобы все java-классы текущего проекта указывали на эту папку как на первую после ключевого слова package . Если хоть у одного класса в этом проекте папка io не будет прописана — то такой класс как бы и не в проекте, а просто мусор в папке.

Имена пакетов

  • Имя состоит из одного слова (желательно).
  • Без заглавных букв (желательно).

Например, package com.MySuperLongPackageName.view — плохая практика именования пакетов.

Совокупность имен под-пакетов делает проект уникальным, не похожим на миллионы других. Даже если, в каждом проекте в мире, 100% будет класс Main.java — то они маловероятно пересекутся и помешают друг-другу. Но даже если пересекутся — это решаемо, рассмотрим это в дальнейших примерах.

Применение пакетов

Адреса (пакеты) классам, в нашем проекте, мы уже выдали. Они нужны для доступа классов друг к другу.

Как уже было сказано выше — пакет можно сравнить с адресом. Рассмотрим это на примере ветвления папок(пакетов).

Допустим, в классе StartClass.java нам нужно создать экземпляр класса SomeView.java , для использования его метода message() . Как это можно реализовать:

Только благодаря прописанному пути к классу SomeView , класс StartClass может вообще узнать о его существовании.

Но прописывание таких длинных путей ( io.hexlet.xo.view.SomeView ) — просто не удобно. Поэтому, к нам на выручку, приходит импортирование.

Импортирование пакетов

Для того чтобы не писать длинные пути, к каждому конкретному классу, при каждом его использовании — нужно его импортировать. Для этого применяется ключевое слово import . Импорты пишутся между строчкой package . и строчкой объявления класса. Перепишем предыдущий пример StartClass с применением ключевого слова import :

Если в пакете io.hexlet.xo.view очень много разных классов. И они нам все нужны тут, в классе StartClass , как их все разом заимпортировать?

Решение приходит со звездочкой * .

Перепишем предыдущий пример с импортированием любых классов из пакета io.hexlet.xo.view :

В случае возникновения коллизий имен классов, например, когда в разных пакетах есть классы с одинаковыми именами и оба пакета импортированы — тогда придется обращаться к таким классам с использованием полных имени пакетов. Например, io.hexlet.xo.view.SomeView . Иначе java не будет знать из какого именно пакета использовать класс, в данном случае.

Импортирование по умолчанию

Независимо от того, написал ли программист вообще слово import , перед определением своего класса — java всегда автоматически, неявно, импортирует в текущий класс два пакета:

  1. java.lang.*; . Вручную в коде это можно прописать так: import java.lang.*; . Это одна из стандартных библиотек java.
  2. Текущий пакет, в котором находится текущий класс. Вручную это выглядело бы так: import . или import полный.путь.к.папке.с.этим.файлом .

Обратите внимание на строку System.out.println("Some very important message!"); в классе SomeView :

Класс SomeView видит класс System и его открытые поля, в частности поле out , благодаря стандартному импорту java.lang.*; , т.к. System входит в пакет java.lang .

Статическое импортирование

Этот аспект будет рассмотрен в "Модуль 3. Урок 3. Уровни методов в Java." Поскольку там мы лучше познакомимся с ключевым словом static .

Как компилировать классы в пакетах

Для компиляции, используется команда javac .

Для компиляции отдельного файла в конкретном пакете, нужно прописать команду так: javac src/com/package_name/package_name/ClassName.java . Обратите внимание, что для команды javac — мы прописываем все пути через слеш ( / ), а не через точки. И обязательно нужно указать расширение файлов ( .java ).

Если этот файл (класс) ClassName.java использует в своем коде другой класс, из соседнего пакета — это уже зависимость. Нужно подсказать компилятору, где еще лежат исходники (сорцы), от которых может зависеть компилируемый класс, с помощью ключа -sourcepath . Выглядит это так: javac -sourcepath src . А потом уже пишем путь к компилируемому файлу: src/com/package_name/package_name/ClassName.java . Целиком, в терминале, команда будет выглядеть так: javac -sourcepath src src/com/package_name/package_name/ClassName.java . -sourcepath src можно написать и в конце данной строки.

Для того чтобы класс-файлы не лежали рядом с исходниками, а в отдельной папочке, можно применить ключ -d , а за ним имя существующей папки, в которую складываются скомпилированные классы. Переделаем предыдущий пример так: javac src/com/package_name/package_name/ClassName.java -sourcepath src -d out .

Для того, чтобы компилятор прошелся по всем директориям в папке, например, src и скомпилировал там все исходники — нужно ввести команду так: javac src/**/*.java (пройтись по всем под папкам в папке src и скомпилировать там все файлы *.java ). Правда они опять будут лежать радом с исходниками. Лучше сразу разложить класс-файлы в отдельную папку: javac src/**/*.java -d out . Все скомпилированные классы будут разложены по пакетам так же как они располагались в папке src .

А если эти классы в папке src зависят друг от друга, то команда будет выглядеть так: javac src/**/*.java -d out -sourcepath src . В результате чего компилятор скомпилирует все *.java -файлы в *.class -файлы, свяжет их по зависимостям и уложит в директорию out .

Некоторые терминалы не понимают звездочки ** . Например, команда javac src/**/*.java может просто выдавать ошибку отсутствия файлов. "Понимание звездочек" нужно включать! В bash это можно включить командой: shopt -s globstar .

Как запускать классы в пакетах

Для запуска java-приложений используется команда java .

Для запуска отдельных классов, которые не в пакетах, используется простой подход, например: java Main , java Start , java MyStartClass . Главное чтобы в этом классе был специальный метод:

Именно с него начинается работа самостоятельной java-программы. В остальных классах одной программы — этот метод не нужен.

А для запуска "пакетного" класса на исполнение требуется иной подход.

Запустим наш класс StartClass .

Поскольку наш исполняемый файл StartClass.class лежит в отдельной папочке и в своей некой ветке директорий (пакете), то теперь нужно не просто написать java StartClass , а указать:

  • classpath (путь к папке со всеми пакетами и скомпилированными классами в них);
  • путь к стартовому классу в пакетной структуре этого класса.

-classpath , сокращенно: -cp . После этого ключа нужно указать имя папки, в которой лежат пакеты содержащие скомпилированные классы, в нашем случае это out .

Путь к стартовому классу, в пакетной структуре программы, нужно прописывать через точку: io.StartClass .

Команда запуска StartClass.class в одну строчку будет выглядеть так: java -cp ./out io.StartClass .

  • В данной команде ключ пути к классам ( -cp ) должен идти первым, а потом уже путь и имя запускаемого класса.
  • И имя класса должно быть без расширения .class (в отличие от javac )!
  • Для запуска программы нужно указывать только тот класс, который содержит main -метод, остальные зависимости будут найдены и подключены из папки out автоматически, благодаря ключу -cp .

Полезные ссылки:

  • Правильная инсталляция JDK и настройка переменных окружающей среды. Чтобы работала команда javac
  • Не проходит команда со звездочками javac src/**/*.java ? Решение:
      . .

    Документация

    Аватары экспертов Хекслета

    Остались вопросы? Задайте их в разделе «Обсуждение»

    Вам ответят команда поддержки Хекслета или другие студенты.

    Об обучении на Хекслете
    • Статья «Как учиться и справляться с негативными мыслями»
    • Статья «Ловушки обучения»
    • Статья «Сложные простые задачи по программированию»
    • Урок «Как эффективно учиться на Хекслете»
    • Вебинар «Как самостоятельно учиться»

    Открыть доступ

    Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

Похожие статьи