Java неявно дают приоритет доступа к пакетам более подклассов, поскольку модификатора по умолчанию предоставляет доступ к пакетам, но не подклассам, защищенного разрешает доступ к обеим, но нет никаких модификаторов, которые разрешают доступ к подклассы, но не пакеты. Это всегда было странно для меня, потому что я, естественно, склонен рассматривать подклассы «ближе» к родителям (даже потому, что они сами являются их собственными переменными), тогда классы в одном пакете, и часто я нахожусь в ситуации, когда я хотел бы иметь модификатор для sub, но не для пакета. Это, вероятно, означает, что я использую пакеты «неправильно», но может ли кто-нибудь объяснить мне логику этого решения?Java Модификатор доступа приоритет
ответ
Когда вы используете модификатор protected
, вы предоставляете неограниченный доступ к классу. Можно будет расширить его, когда захотите, даже если класс будет неприемлемым для подкласса. Когда вы используете модификатор protected
, вы, по сути, говорите, что класс будет (в обозримом будущем) всегда быть подходящим для подкласса. Это может быть не то, что вы хотите; например, если у вас есть класс, который предполагается продлить несколько раз для проекта, и не более того после этого.
Если у вас нет модификатора (по умолчанию-access/package-private), вы предоставляете ограниченный доступ к классу. Никто, даже вы, не будет иметь доступ к этому классу за пределами пакета, что вам нужно, если вы делаете что-то вроде вышеупомянутого случая, где класс специфичен для вашего проекта и распространяется на любой другой произвольный проект будет неуместным. Вот список из самого высокого доступа к низшему доступа:
public
: Неограниченный доступ ко всем и всеprotected
: Неограниченный доступ, но более ограничительный- по умолчанию доступа: Ограниченный доступ к конечному количеству других классов
private
: Чрезвычайно ограниченный доступ: не доступны ничего бы то ни было
Чтобы иметь пятый модификатор доступа между protected
и доступ по умолчанию, чтобы каждый класс в любом месте, который хочет его расширить, должен иметь к нему доступ, но не иметь доступ, если он не хочет расширять его, является избыточным, поскольку он уже существует в форме public abstract
.
I find myself in the situation where I would like to have the modifier for sub but not for the package
Почему? Если вы выставляете что-то для размещения членов пакета, то вам все равно не использовать их, если это не нужно. Идея пакета, занимающая приоритет над наследованием, заключается в том, что он позволяет вам инкапсулировать функциональность в составе нескольких классов без необходимости вложенности друг в друга.
Рассмотрите возможность совершения покупки. У вас есть класс автомобиля и класс колеса в том же пакете. Вы хотите разоблачить методы некоторых колес для всех (getRadius(), getColor(), geAngularSpeed ()), но вы также хотите, чтобы некоторые методы были скрыты от всего, кроме класса автомобиля (setAngularSpeed ()).
Применения должны быть модульными, это факт. Кроме того, модули должны иметь средства для связи друг с другом. Эти два варианта использования - это дефолтные и защищенные пакеты.
Обычно файлы, относящиеся к модулю, который вы строите, находятся в одном пакете. Например:
--my_module
|-- MainModuleClass
|-- HelperA
|-- HelperB
В этом случае, как правило, имеет MainModuleClass
поля типа HelperA
и HelperB
и команды разработки модуля созданы все 3 класса - таким образом, «они знают, что они делают». Кроме того, все эти 3 класса имеют очень важные обязанности - они составляют основу вашего модуля. По этим двум причинам это отличное место для использования «доступа к пакету», поскольку вы можете чувствовать себя довольно безопасным доступом к членам каждого другого класса.
Кроме того, тесты для этого модуля находятся в том же пакете, что и сам модуль (в любом другом каталоге, но это не имеет значения). Поэтому авторы модуля могут получить доступ к полям «по умолчанию» классов модулей, чтобы прочитать их внутреннее состояние и проверить правильность внутреннего поведения.
Теперь, если какой-либо другой разработчик решил добавить некоторые функции, расширив один из этих классов, этот программист по определению является «другим» программистом. Он не знает код, а также первую команду, которая создала оригинальный компонент. Поэтому некоторые поля отмечены как «защищенные», чтобы предоставить доступ только «аутсайдерам», которые хотят расширить код и чувствовать себя в безопасности.
Резюмируя:
- Если вы строите модуль и хотите, чтобы некоторые поля, чтобы можно было использовать только классы в вашем модуле - по умолчанию видимость путь.
- Если некоторые поля должны быть расширены или использованы какой-либо другой командой, которые могут захотеть повторно использовать ваш модуль - эти поля должны быть защищены.
Не были ли подклассы естественно в одном пакете? – Gendarme
@ Gendarme так же, как каждое ваше приложение для качания попадает в пакет javax.swing? –
@CoderinoJavarino только потому, что кто-то работает над приложением, не означает, что это публичная библиотека для внешнего использования. OP вполне мог бы сделать частный проект, в котором все подклассы были бы упакованы с банкой. –