Почему ключевое слово "package" и .h?

1) Почему в файлах, которые находятся в пакете Java, я записываю в нем "пакет", не косвенно предполагая, что если он находится в каталоге, то это в пакете?.

2) Я пришел из мира С++. Я всегда импортировал .h из классов, которые мне нужны из других файлов, которые используют этот класс (я имею в виду, я хочу только "показать" заголовок, а не реализацию). Но теперь я немного запутался в импорте на Java. Как это делается на Java?

Спасибо

Ответ 1

  • Нет, это не предполагается. В конце концов, что вызвал мой пакет? com.mypackage.stuff? src.com.mypackage.stuff? myproject.com.mypackage.stuff? C.Users.makakko.workspace.myproject.src.com.mypackage.stuff?

    Если вы устанавливаете только пакет из папок, то это относится к корню диска? Что делать, если проект разработан на другой букве диска на другой машине? Это относительно местоположения javac.exe? Опять же, как насчет разных каталогов установки? Как насчет рабочего каталога при запуске javac? Но вы можете указать местоположение для javac, чтобы найти исходные файлы. Что делать, если вы хотите сделать простую тестовую программу или научить кого-то Java, который никогда не программировался раньше; вам нужно использовать/объяснить всю концепцию структуры пакета?

    Если вы опускаете спецификатор package, то вы все еще в пакете. Это просто "пакет по умолчанию", который не имеет имени.

  • Заголовочные файлы являются скорее артефактом из того, как нужно компилировать C, а не способом скрытия информации. В C должен быть определен метод, прежде чем он сможет ссылаться. Если вы хотите иметь несколько методов, которые ссылаются друг на друга, вы должны определить их все, прежде чем использовать любой из них, следовательно, заголовок. Заголовки в С++ переносятся с этого, но изменения в С++ изменяют необходимость заголовков.

    В Java компилятор будет рассматривать все ваши подписи метода и класса, прежде чем делать что-либо, что требует метода/класса. Функция, обслуживаемая заголовками, помещается в сам компилятор. Вы не можете зависеть от заголовка для скрытия информации, потому что

    • Код может быть помещен в файл заголовка

    • Если вы не используете скрытую информацию, например отдельную библиотеку, программист может найти файл c/cpp, соответствующий заголовку без проблем

    Аналогично в Java вы можете получить только скрытую информацию, удалив исходный код. После того как вы сделали недоступным источник, вы открываете API с общедоступными/защищенными классами, перечислениями и интерфейсами. Для получения бонусных баллов напишите пояснительные комментарии JavaDoc для всего и запустите javadoc.exe над своим источником, чтобы подготовить отдельную документацию для тех, кто будет использовать ваши пакеты.

Ответ 2

1) Объявление package должно соответствовать иерархии каталогов в проекте.

Если я использую package com.stackoverflow.bakkal; в Car.java, тогда ожидается следующая иерархия.

com/
|-- stackoverflow/
|   `-- bakkal/
|       |-- Car.java

2) Если вы хотите скрыть реализацию, вы можете использовать interface в Java вместо class. Затем распределите фактические реализации в файлах .class или JAR, например.

Mmm, но интерфейс не может быть экземпляр...

Интерфейс работает как прототип в С++ в некоторой степени. У вас есть контракт, тогда фактическая реализация происходит из других источников.

Я хочу создать экземпляр класса, но без предоставления реализации, только прототип

Это невозможно даже С++, как вы можете что-то создать, не имея своей реальной реализации? В С++ вам все равно нужно связать с объектными файлами. В Java вы используете файлы .class.

Ответ 3

Пакеты не предполагаются, потому что философия Java состоит в том, что лучше быть явным, чем неявным/предполагаемым.

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

Вот почему вы склонны видеть:

import java.util.ArrayList;
import java.util.LinkedList;

вместо:

import java.util.*;

Это может показаться раздражающим до тех пор, пока в один прекрасный день вы не попытаетесь найти кого-то из кода elses, и это поразит вас, насколько сложнее это было бы, если бы вещи были скрыты/подразумевались.

Если вы используете Eclipse, Netbeans или IntelliJ, вы даже не заметите из-за двух особенностей.

Прежде всего, если вы нажмете ctrl-space в середине ввода имени класса, оно не только заполнит имя класса для вас, но также автоматически добавит его в список импорта.

Во-вторых, если вы когда-нибудь доберетесь до того, где импортируются "Неверные" или вы не используете расширение ctrl-space, вы можете просто набрать ctrl-shift-o (eclipse), чтобы он "Fix import". Это автоматически импортирует все, что нужно импортировать и удалять импорт, который вам больше не нужен. В зависимости от ваших настроек он также будет расширяться или сворачиваться *.

Как только вы получаете систему вниз, вы даже не рассматриваете импорт.

Ответ 4

Пакет указывает путь к классу. Он должен соответствовать каталогу на диске или в банке (zip). Местоположение относится к местоположению на пути к классам. Защищенный доступ ограничен классами в одном пакете.

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

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

Реализация на самом деле не видна с помощью импорта (по крайней мере, не выше, чем предоставленный скомпилированным классом). Видно, что это общедоступные методы и данные видимого интерфейса. Для импорта из тех же методов и данных, которые не имеют доступа (public/protected/private). Защищенные методы и переменные видны для подклассов класса. Файлы h могут использоваться без предоставления исходных или объектных файлов. Импорт требует предоставления указанных классов (класс может состоять из только постоянных, хотя это будет плохой дизайн.)