Ответ 1
В своей книге Герберт Шильдт говорит на стр. 172 (3-й абзац), что "защита применяется только при наследовании".
Есть аргумент, что это утверждение верно, хотя я бы сказал, что он довольно вводит в заблуждение. Посмотрите диаграмму доступа из учебника по управлению доступом:
Modifier Class Package Subclass World public Y Y Y Y protected Y Y Y N no modifier Y Y N N private Y N N N
Обратите внимание, что ни один модификатор не предоставляет доступ к классу и пакету члену и не предоставляет доступ к подклассам или миру. protected
изменяет только одну из этих вещей: он делает доступным элемент для подклассов. Поэтому в этом смысле он исправляет: применяется только при наследовании; без наследования, он не имеет модификатора.
Но я нахожу это довольно вводящим в заблуждение, по той самой причине, которая вызвала ваш вопрос: кажется, подразумевает, что доступа к пакетам не будет. Единственный способ, который имеет смысл в заявлении, заключается в том, что вы уже знаете, что никакой модификатор не предоставляет доступ к пакету.
Для ясности: protected
означает, что член доступен для любого класса в пакете и для кода в подклассах. Это позволяет библиотеке иметь поля и методы, из которых вы получаете доступ только от кода, который является частью библиотеки * (вид, см. Ниже) или код, который помогает реализовать что-то в библиотеке (например, если вы являетесь подклассом из один из классов библиотеки). Нет особого "почему", кроме того, как был разработан язык.
Если это так, я не вижу разницы между публичными и защищенными спецификаторами в этой ситуации.
В этой ситуации нет. Очевидно, что очень большая разница, однако, когда вы рассматриваете код, который не находится в одном пакете и не находится в производном классе члена пакета: этот код не имеет доступа к членам protected
.
Это описано в JLS§6.6.1:
... если член или конструктор объявлен
protected
, тогда доступ разрешен только тогда, когда выполняется одно из следующих условий:
Доступ к члену или конструктору происходит изнутри пакета, содержащего класс, в котором объявлен защищенный член или конструктор.
Доступ является правильным, как описано в разделе 6.6.2.
(обратите внимание на первую пулю) и JLS§6.6.2:
A
protected
член или конструктор объекта может быть доступен извне пакета, в котором он объявляется только кодом, ответственным за реализацию этого объекта.
( "код, который отвечает за реализацию этого объекта"; — например, код в подклассе.)
* Повторите мой "вид", см. ниже "on". Это позволяет библиотеке иметь поля и методы, из которых вы получаете доступ только от кода, который является частью библиотеки... "Это не так, потому что, за исключением ограниченные пакеты (например, java.lang
), вы можете с радостью написать свой собственный класс, говорящий об этом в библиотечном пакете, а затем использовать поля уровня пакета и методы классов библиотеки. Концепция пакета Java не является механизмом защиты полей/методов.