В чем разница между общедоступным, защищенным, частным пакетом и частным в Java?

Есть ли в Java четкие правила относительно того, когда использовать каждый из модификаторов доступа, а именно значение по умолчанию (частный пакет), public, protected и private, при создании class и interface и работе с наследованием?

private скрывается от других классов внутри пакета. public предоставляет классы вне пакета. protected - это версия public, ограниченная только подклассами.
Museful 13.02.2013 13:56

@Tennenrishin - Нет; В отличие от C++, в Java protected делает этот метод доступным также из всего пакета. Эта глупость в модели видимости Java нарушает цель protected.

Nicolas Barbulesco 21.08.2013 13:51

@Nicolas Доступен из всего пакета, с protected или без него. В качестве модификатор доступа все, что делает protected, - это предоставлять подклассам вне пакета.

Museful 14.03.2014 14:59

@tennenrishin - ну, это то, что сказал Николас ... и вы просто повторяете это сейчас. Первоначально вы сказали, что protected - и я цитирую - `` это версия public, ограниченная только подклассами '', что неверно, по вашему собственному признанию, поскольку protected также разрешает доступ через весь пакет (следовательно, он не предоставляет ограничивать доступ к подклассам .)

luis.espinal 07.04.2014 17:45

Я также согласен с Николасом в том, что режим защищенного доступа в Java - это идиотизм. Случилось так, что Java объединила квалификаторы горизонтального (решетчатого) и вертикального ограничения доступа. Область действия по умолчанию - это ограничение по горизонтали / решетке, при этом решетка является пакетом. Public - еще одно горизонтальное ограничение, где решетка - это весь мир. Частные и (C++) защищенные - вертикальные. Было бы лучше, если бы у нас был сквозной доступ, скажем, protected-package для тех редких случаев, когда он нам действительно нужен, оставив protected эквивалентным защищенной версии C++.

luis.espinal 07.04.2014 17:53

@ luis.espinal Тогда он просто повторял то, что было сказано в первом комментарии. Вы не можете раскрыть то, что уже видно, и утверждение, что protected является ограниченным экспонентом, не означает, что это прячется что-то. В противном случае даже «public предоставляет классы вне пакета» будет означать, что publicпрячется из классов внутри пакета.

Museful 27.01.2015 22:43

Принятый ответ не является неправильным, он просто неполный и простое задание копирования + вставки с внешнего ресурса. Ответ @Mechanical snail (stackoverflow.com/a/12401576/639520) намного лучше IMO.

E-Riz 01.09.2015 18:28

@NicolasBarbulesco В отличие от C++? В C++ нет пакетов, вы не сможете сделать метод доступным для ряда классов, если не сделаете каждый из них другом класса вручную. Если бы в Java не было концепции пакетов, она работала бы точно так же. Говоря о глупости, код из одного и того же пакета в любом случае должен исходить от одного и того же разработчика, поэтому я не вижу здесь большой проблемы.

Malcolm 05.11.2015 19:39

@Malcolm - «код из одного и того же пакета в любом случае должен исходить от одного разработчика» Кто это сказал? Часто это не так.

Nicolas Barbulesco 20.11.2015 13:02

@NicolasBarbulesco Я не понимаю, как это возможно, если пакеты имеют правильный префикс домена разработчика.

Malcolm 20.11.2015 13:06

Больше никто не заметил прикол, что модератор Mystical protected на этот вопрос не дает ответить все ?? Гений!

NoName 23.06.2017 11:42

@Malcolm, это неправда, мы регулярно помещаем наши собственные классы в те же пакеты, что и библиотеки, из-за частного доступа к пакету

Enerccio 18.05.2018 10:12

@Enerccio Что не так? Я не говорил, что этого никто не делает. Это плохая практика, вы получаете доступ к некоторым частным API таким образом, что делает код хрупким, а начиная с Java 9 пакеты, разделенные по модулям, вообще не разрешены.

Malcolm 18.05.2018 16:28

Частный пакет @Malcolm был просто плохой идеей, и у java никогда не должно было быть такого. Недавно мне пришлось создать элемент JSON по умолчанию, который не будет генерировать NPE, если данные были нулевыми, но я не мог этого сделать, потому что один метод в JSONElement был закрытым для пакета. Так что мне пришлось обмануть это.

Enerccio 19.05.2018 17:01

@Enerccio Я не понимаю, насколько неудобный дизайн API делает это ошибкой Java.

Malcolm 20.05.2018 00:32

@Malcolm java виноват в том, что есть частный пакет

Enerccio 21.05.2018 08:27

@Enerccio Вы уже заявили об этом, но не привели аргументов. Мы можем продолжить в чате.

Malcolm 21.05.2018 12:41
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3 321
17
2 245 451
29
Перейти к ответу Данный вопрос помечен как решенный

Ответы 29

Ответ принят как подходящий

Официальный учебник может быть вам полезен.


КлассУпаковкаПодкласс
(тот же пакет)
Подкласс
(diff pkg)
Мир
public+++++
protected++++
без модификатора+++
private+

+: доступно
пусто: недоступно

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

niks 01.09.2017 11:35

Я до сих пор не могу различить «общедоступный» и «защищенный». И что в этом ответе «Мир». Означает ли это доступ из папки проекта в другом проекте и пакете ?? Но этого не происходит. Нужна помощь в этом.

Deepak 25.04.2018 15:25

@Deepak, Мир в твоем проекте. Если у вас есть общедоступный класс, любой другой класс может создать его экземпляр. То же, что и методы. Если он открыт, любой, кто использует этот класс, может использовать этот метод. Пакет относится к «папке», в которой вы находитесь. Итак, ca.my.package.controllers отличается от ca.my.package.models. Общедоступные элементы доступны вне этих пакетов, а остальные - нет. package-private, по сути, считаются общедоступными в пакете. Защищенный означает все, что наследует его или находится в том же пакете. Private удаляет весь доступ извне, включая пакет.

adprocas 03.05.2018 15:59
Мир внутри вашего проекта. Я должен объяснить дальше. Библиотеки находятся внутри вашего проекта, и если вы создаете библиотеку, они также будут предоставлять эти общедоступные классы и методы. Так что говорить только в рамках вашего проекта - это немного неуместно. «Все, кто его использует» - лучшее описание.
adprocas 03.05.2018 16:02

@adpro - я попытался сделать методы общедоступными и защищенными, но оба этих типа методов доступны за пределами их основного пакета, и пользователь должен расширить родительский класс в обоих случаях, что совершенно очевидно. Я до сих пор не уверен в разнице. Может помочь еще немного объяснений или уловок.

Deepak 04.05.2018 09:23

@Deepak, если вы расширяете (наследуете) класс, то этот наследующий класс будет иметь доступ ко всем общедоступным и защищенным методам и свойствам. Если вместо этого вы создадите экземпляр этого класса в другом классе (не расширяете) и попытаетесь сделать что-то вроде object.protectedMethod() для защищенного метода, вы не сможете этого сделать, если он не находится в том же пакете.

adprocas 04.05.2018 15:22

Например, если у меня есть MyClass, а я использую AnotherClass extends MyClass, у меня будет доступ ко всем защищенным и общедоступным методам и свойствам из AnotherClass. Если я где-нибудь сделаю MyClass myClass = new MyClass(); в AnotherClass - скажем, конструктор - у меня будет доступ к общедоступным методам, только если он находится в другом пакете. Обратите внимание, что если я использую = new MyClass() { @Override protected void protectedMethod() { //some logic } };, похоже, что я могу получить доступ к защищенным методам, но это то же самое, что и расширение, но вместо этого встроено.

adprocas 04.05.2018 15:25

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

Dawood ibn Kareem 11.07.2018 09:26

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

Anatolii Stepaniuk 06.09.2018 10:04

@DawoodsaysreinstateMonica Это отличный ответ, это именно то, что ищет большинство людей, которые находят эту страницу. Кроме того, эта таблица взята из официального руководства Oracle. Но как насчет того, чтобы дать нам ссылку, чтобы мы узнали, что на самом деле означает «защищенный»?

Heinzlmaen 06.02.2020 17:58

protected доступен только в том же пакете. Он недоступен вне этого пакета. Спецификатор protected в Java называется спецификатором уровня пакета.

Badri Paudel 08.05.2020 13:18

@UsagiMiyamoto: Не могли бы вы подробнее рассказать о том, как «частные члены могут быть видны / использованы любым классовым / статическим методом в одном и том же исходном файле»?

jayjay 30.07.2020 01:44

@niks: я могу получить доступ к защищенным членам из подкласса разных пакетов

jayjay 30.07.2020 01:46

Доступ к защищенным членам @niks МОЖЕТ получить доступ подклассам из другого пакета. Разве не в этом суть? Иначе какая разница между по умолчанию и защищенным?

Jack 15.10.2020 15:30

@Jack Да, комментарий niks неверен, несмотря на то, что многие положительные отзывы говорят об обратном. Ссылка на учебные пособия по Java в ответе четко говорит, что к защищенным членам также можно получить доступ в подклассах из другого пакета. Похоже, он / она имел в виду «уровень пакета» вместо «защищенный» или имел в виду другое редактирование.

Piovezan 05.02.2021 05:57

@DawoodsaysreinstateMonica Я думаю, что проблема здесь в том, что заголовок и тело задают два разных вопроса: «В чем разница между модификаторами доступа» и «Когда следует использовать разные модификаторы доступа». Этот ответ отвечает на вопрос в заголовке, но не на вопрос в теле.

M. Justin 17.02.2021 10:38

Простое правило. Начните с объявления всего приватным. А затем продвигайтесь к общественности по мере возникновения потребностей и того, что того требует дизайн.

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

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

Кроме того, используйте аннотацию @Override при переопределении, чтобы не допустить поломки при рефакторинге.

@RuchirBaronia, "world" = весь код в приложении, независимо от того, где он находится.

Andrejs 26.02.2016 22:12

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

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

Частный

Как вы могли подумать, его может увидеть только класс, в котором он объявлен.

Пакет Частный

Его можно увидеть и использовать только тем упаковка, в котором он был объявлен. Это значение по умолчанию в Java (что некоторые считают ошибкой).

Защищено

Пакет Private + можно увидеть подклассам или членам пакета.

Общественные

Это все видят.

Опубликовано

Виден за пределами контролируемого мной кода. (Хотя это и не синтаксис Java, он важен для этого обсуждения).

C++ определяет дополнительный уровень, называемый «друг», и чем меньше вы об этом знаете, тем лучше.

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

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

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

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

Вот здесь-то и появляется идея «опубликованного». Для изменения интерфейса (его рефакторинга) необходимо найти весь код, который его использует, и изменить его. Если интерфейс частный, нет проблем. Если он защищен, вам нужно найти все свои подклассы. Если он общедоступен, вам нужно найти весь код, который использует ваш код. Иногда это возможно, например, если вы работаете над корпоративным кодом, предназначенным только для внутреннего использования, не имеет значения, является ли интерфейс общедоступным. Вы можете взять весь код из корпоративного репозитория. Но если интерфейс «опубликован», если есть код, использующий его вне вашего контроля, то вы попали в беду. Вы должны поддерживать этот интерфейс, иначе вы рискуете взломать код. Даже защищенные интерфейсы можно считать опубликованными (поэтому я не заморачиваюсь с защищенными).

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

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

Sebastian Mach 07.06.2011 14:13

Следует также отметить, что «защищенный» в C++ имеет другое значение - защищенный метод фактически является закрытым, но все же может вызываться из наследующего класса. (В отличие от Java, где он может вызываться любым классом в одном пакете.)

Rhys van der Waerden 02.10.2011 16:34

@RhysvanderWaerden C# в этом аспекте совпадает с C++. Мне кажется довольно странным, что Java не позволяет объявлять член, доступный для подкласса, но не для всего пакета. Для меня это вроде как перевернутое - пакет шире, чем дочерний класс!

Konrad Morawski 15.10.2013 21:36

Пакет @KonradMorawski IMHO имеет меньшую область действия, чем подкласс. Если вы не объявили свой класс final, пользователи должны иметь возможность создавать подклассы, поэтому защита java является частью вашего опубликованного интерфейса. OTOH, пакеты неявно разрабатываются одной организацией: например, com.mycompany.mypackage. Если ваш код объявляется в моем пакете, вы неявно объявляете себя частью моей организации, поэтому мы должны общаться. Таким образом, пакет публикуется для меньшей / более доступной аудитории (люди в моей компании), чем подкласс (люди, которые расширяют мой объект), и поэтому считается более низкой видимостью.

Eponymous 23.05.2014 00:37
friend подходит только для особых случаев, таких как классы перегрузки. в противном случае это плохая практика для архитектурного дизайна, так как это испортит концепцию многоуровневости
Khaled.K 28.05.2014 09:36
friend хорош для определения особых отношений между классами. Во многих случаях при правильном использовании он обеспечивает превосходную инкапсуляцию. Например, он может использоваться привилегированным классом фабрики для внедрения внутренних зависимостей в сконструированный тип. У него плохая репутация, потому что люди, которые не заботятся о правильной поддержке хорошо спроектированной объектной модели, могут злоупотреблять ею, чтобы облегчить свою рабочую нагрузку.
Dennis 08.12.2014 13:05

@ konrad-morawski В очень древние времена (до 1.03) Java имела дополнительный модификатор доступа private protected, который делал именно это. Было несколько причин, по которым он был удален, но основная, на мой взгляд, заключается в том, что пакет в Java является действительно имеет более узкую область действия, чем дочерний класс (который обычно находится в каком-то другом пакете), поэтому этот доступ не имел реального смысла. Я на самом деле использовал его пару раз тогда, но так и не нашел подходящего случая для его использования. Я виню свои корни C++ :)

Tomas 29.10.2015 13:45

В Java private предотвращает переопределения, protected - нет (но также не полностью публично), поэтому все они имеют свое применение.

User 08.10.2016 12:48

«Как только интерфейс становится более чем частным, он выходит за рамки вашего контроля» - это верно только для тех, кто игнорирует видимость пакетов, как и вы. Все модификаторы важны для сокрытия информации, и пакет обычно создается небольшой тесно сотрудничающей командой, которая рассматривает все видимые методы пакета как частные для них. +++ Точно так же friend не предназначен для того, чтобы нанести ущерб видимости, но позволяет еще больше ужесточить правила при добавлении исключения (любой механизм исключения подвержен злоупотреблениям; поэтому видимость пакетов лучше, но, возможно, раз в месяц я тоже можно использовать friend).

maaartinus 10.06.2017 12:24

Ответ Дэвида объясняет значение каждого модификатора доступа. Что касается того, когда использовать каждый из них, я бы предложил сделать общедоступными все классы и методы каждого класса, которые предназначены для внешнего использования (его API), а все остальное - частным.

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

Эта страница хорошо описывает модификатор доступа по умолчанию и защищенный

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

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

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

Anand 27.10.2012 22:55

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

Доступ «по умолчанию» (определяемый отсутствием ключевого слова) также называется пакет-частный. Исключение: в интерфейсе отсутствие модификатора означает открытый доступ; модификаторы, отличные от public, запрещены. Константы перечисления всегда открыты.

Резюме

Разрешен ли доступ к члену с этим спецификатором доступа?

  • Член - private: только если член определен в том же классе, что и вызывающий код.
  • Член является частным пакетом: только если вызывающий код находится в пакете, непосредственно включающем член.
  • Член - protected: тот же пакет, или если член определен в суперклассе класса, содержащего вызывающий код.
  • Участник - public: Да.

Какие спецификаторы доступа применяются к

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

Для классов в верхней области разрешены только public и package-private. Этот выбор конструкции предположительно обусловлен тем, что protected и private будут избыточными на уровне пакета (нет наследования пакетов).

Все спецификаторы доступа возможны для членов класса (конструкторы, методы и статические функции-члены, вложенные классы).

Связанный: Доступность класса Java

Приказ

Спецификаторы доступа могут быть строго упорядочены

public > protected > package-private > private

Это означает, что public обеспечивает наибольший доступ, а private - наименьший. Любая ссылка, возможная на частном члене, также действительна для частного члена пакета; любая ссылка на частный член пакета действительна для защищенного члена и т. д. (Предоставление доступа к защищенным членам другим классам в том же пакете считалось ошибкой.)

Ноты

  • Методы класса являются разрешают доступ к закрытым членам других объектов того же класса. Точнее, метод класса C может обращаться к частным членам C на объектах любого подкласса C. Java не поддерживает ограничение доступа по экземплярам, ​​только по классам. (Сравните со Scala, который поддерживает его с помощью private[this].)
  • Для создания объекта вам нужен доступ к конструктору. Таким образом, если все конструкторы являются частными, класс может быть создан только кодом, живущим внутри класса (обычно статические фабричные методы или инициализаторы статических переменных). Аналогично для конструкторов с закрытым пакетом или защищенными конструкторами.
    • Наличие только частных конструкторов также означает, что класс не может быть подклассом извне, поскольку Java требует, чтобы конструкторы подкласса неявно или явно вызывали конструктор суперкласса. (Однако он может содержать вложенный класс, являющийся его подклассом.)

Внутренние классы

Вы также должны учитывать области действия вложенный, такие как внутренние классы. Примером сложности является то, что внутренние классы имеют члены, которые сами могут принимать модификаторы доступа. Таким образом, у вас может быть частный внутренний класс с открытым членом; можно получить доступ к члену? (См. Ниже.) Общее правило - смотреть на область видимости и думать рекурсивно, чтобы увидеть, можете ли вы получить доступ к каждому уровню.

Однако это довольно сложно, и для получения полной информации используйте обратитесь к Спецификации языка Java. (Да, в прошлом были ошибки компилятора.)

Чтобы понять, как они взаимодействуют, рассмотрим этот пример. Возможна «утечка» частных внутренних классов; обычно это предупреждение:

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}

Вывод компилятора:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error

Некоторые связанные вопросы:

"модификаторы, отличные от общедоступных, запрещены" - начиная с Java 9 это больше не так: интерфейсы также могут иметь частные методы.
MC Emperor 25.08.2018 23:34

Очень коротко

  • public: доступен отовсюду.
  • protected: доступен классам одного и того же пакета и подклассам, находящимся в любом пакете.
  • по умолчанию (модификатор не указан): доступен классам того же пакета.
  • private: доступен только в том же классе.

Как правило большого пальца:

  • private: объем класса.
  • default (или package-private): объем пакета.
  • protected: package scope + child (как package, но мы можем создать подклассы из разных пакетов). Модификатор protected всегда сохраняет отношения «родитель-потомок».
  • public: везде.

В результате, если мы разделим право доступа на три права:

  • (Прямой (вызов из метода внутри того же класса или через синтаксис «this»).
  • (Справка (вызвать метод, используя ссылку на класс или синтаксис «точка»).
  • (Наследование (через создание подклассов).

тогда у нас есть эта простая таблица:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+
____________________________________________________________________
                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |    
Modifier of x \ |               |           |               |       
————————————————*———————————————+———————————+———————————————+———————
public          |       ✔       |     ✔     |       ✔       |   ✔  
————————————————+———————————————+———————————+———————————————+———————
protected       |       ✔       |     ✔     |       ✔       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
private         |       ✔       |     ✘     |       ✘       |   ✘    
____________________________________________________________________

Стоит выразить словами: «Модификатор Protected делает объект доступным для других пакетов, тогда как модификатор default / no ограничивает доступ к тому же пакету»

vanguard69 15.08.2016 19:53

@ vanguard69, модификатор protected делает отмеченный предмет (класс, метод или поле) доступным для некоторого другого класса в каком-то другом пакете. только тогда и только тогда говорит, что другой класс является подклассом класса, в котором объявлен этот помеченный protectedпредмет.

Abdull 15.08.2016 21:14

"без субтитров"? "этот подкласс в другом пакете"? Хм. Я думал, что знаю Java.

sehe 10.12.2017 15:24

@AlexanderFarber вы оптимизировали для конкретной конфигурации браузера? Это мой хром сейчас, а это Fire Fox

sehe 10.12.2017 15:29

Хм, давай вернем мои изменения

Alexander Farber 10.12.2017 17:26

Точки для диаграммы ascii я могу вставить в текстовый файл заметок.

twitchdotcom slash KANJICODER 16.07.2018 08:08

Наиболее неправильно понимаемый модификатор доступа в Java - это protected. Мы знаем, что он похож на модификатор по умолчанию с одним исключением, в котором его могут видеть подклассы. Но как? Вот пример, который, надеюсь, проясняет путаницу:

  • Предположим, что у нас есть 2 класса; Father и Son, каждый в собственном пакете:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
    
  • Добавим в foo() защищенный метод Father.

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
    
  • Метод foo() можно вызывать в 4-х контекстах:

    1. Внутри класса, который находится в том же пакете, где определен foo() (fatherpackage):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
      
    2. Внутри подкласса в текущем экземпляре через this или super:

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
      
    3. Для ссылки того же класса:

      package fatherpackage;
      
      public class Father
      {
          public void fatherMethod(Father f)
          {
              f.foo(); // valid even if foo() is private
          }
      }
      
      -------------------------------------------
      
      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Son s)
          {
              s.foo();
          }
      }
      
    4. Для ссылки, тип которой является родительским классом, и это внутри, пакет, в котором определен foo() (fatherpackage) [Это может быть включено в контекст №. 1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
      
  • Следующие ситуации недопустимы.

    1. Для ссылки, тип которой является родительским классом, а это вне - пакет, в котором определен foo() (fatherpackage):

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
      
    2. Неподкласс внутри пакета подкласса (подкласс наследует защищенные члены от своего родителя и делает их частными для не подклассов):

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }
      
Object#clone() является примером члена protected.
Eng.Fouad 16.11.2013 00:08

В чем разница между выполнением super.foo() и первой недопустимой ситуацией f.foo()?

cst1992 28.10.2017 12:18

@ cst1992 Это сбивает с толку, но см. Спецификацию языка Java 6.6.2: «Доступ к защищенному члену или конструктору объекта может быть получен извне пакета, в котором он объявлен, только кодом, который отвечает за реализацию этого объекта». В super.foo () ссылка «super» «напрямую отвечает за реализацию», а ссылка «f» - нет. Почему? Потому что вы можете быть на 100% уверены, что «super» относится к типу «Отец», но не к «f»; во время выполнения это может быть какой-то другой подтип отца. См. docs.oracle.com/javase/specs/jls/se9/html/…

skomisa 30.01.2018 20:55

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

Dawood ibn Kareem 11.07.2018 09:20

Частный

  • Методы, переменные и конструкторы

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

  • Класс и интерфейс

Модификатор частного доступа - это самый ограничительный уровень доступа. Класс и интерфейсы не могут быть частными.

Примечание

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


Защищено

  • Класс и интерфейс

Модификатор защищенного доступа нельзя применять к классу и интерфейсам.

Методы и поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.

Примечание

Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, предотвращая попытки несвязанного класса использовать их.


Общественные

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

Следовательно, поля, методы и блоки, объявленные внутри общедоступного класса, могут быть доступны из любого класса, принадлежащего Java Universe.

  • Различные пакеты

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

Из-за наследования классов все общедоступные методы и переменные класса наследуются его подклассами.


По умолчанию - без ключевого слова:

Модификатор доступа по умолчанию означает, что мы явно не объявляем модификатор доступа для класса, поля, метода и т. д.

  • В рамках тех же пакетов

Переменная или метод, объявленные без модификатора управления доступом, доступны любому другому классу в том же пакете. Поля в интерфейсе неявно являются общедоступными static final, а методы в интерфейсе по умолчанию общедоступны.

Примечание

Мы не можем переопределить статические поля. Если вы попытаетесь переопределить, это не покажет никаких ошибок но не работает то, что мы кроме.

Связанные ответы

  • Переопределение статических методов в Java

Ссылки ссылки

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.htmlhttp://www.tutorialspoint.com/java/java_access_modifiers.htm

Частный: Ограниченный доступ только к классу

По умолчанию (без модификатора): Ограниченный доступ к классу и пакету

Защищено: ограниченный доступ к классу, пакету и подклассам (как внутри, так и вне пакета)

Общественные: Доступен для класса, пакета (всех) и подклассов ... Короче говоря, везде.

Public Protected Default и private являются модификаторами доступа.

Они предназначены для инкапсуляции или скрытия и отображения содержимого класса.

  1. Класс может быть общедоступным или по умолчанию
  2. Члены класса могут быть общедоступными, защищенными, по умолчанию или частными.

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

Обычно переменные-члены определены как частные, но методы-члены являются общедоступными.

Default не является модификатором доступа, а два других написаны с ошибками.
user207421 24.09.2016 06:13

Модификаторы доступа предназначены для ограничения доступа на нескольких уровнях.

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

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

По умолчанию: Доступен в одном пакете из любого класса пакета.

Для доступа вы можете создать объект класса. Но вы не можете получить доступ к этой переменной вне пакета.

Защищено: вы можете получить доступ к переменным в том же пакете, а также к подклассу в любом другом пакете. так что в основном это поведение по умолчанию + Унаследовано.

Чтобы получить доступ к защищенному полю, определенному в базовом классе, вы можете создать объект дочернего класса.

Частный: может быть доступ в том же классе.

В нестатических методах вы можете получить доступ напрямую из-за ссылки это (также в конструкторах), но для доступа в статических методах вам необходимо создать объект класса.

Видно на упаковке. По умолчанию. Никаких модификаторов не требуется.

Виден только классу (частный).

Виден миру (общественный).

Виден пакету и всем подклассам (защищенный).

Переменные и методы можно объявлять без каких-либо вызываемых модификаторов. Примеры по умолчанию:

String name = "john";

public int age(){
    return age;
}

Модификатор приватного доступа - приватный:

Доступ к методам, переменным и конструкторам, которые объявлены частными, можно получить только внутри самого объявленного класса. Модификатор частного доступа - это самый ограничительный уровень доступа. Класс и интерфейсы не могут быть частными.

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

Использование модификатора private - это основной способ инкапсуляции объекта и скрытия данных от внешнего мира.

Примеры:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

Модификатор публичного доступа - публичный:

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

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

Из-за наследования классов все общедоступные методы и переменные класса наследуются его подклассами.

Пример:

public void cal(){

}

Модификатор защищенного доступа - protected:

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

Модификатор защищенного доступа нельзя применять к классу и интерфейсам. Методы и поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.

Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, предотвращая попытки несвязанного класса использовать их.

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}
  • общественный - доступен из любой точки приложения.

  • дефолт - доступно из пакета.

  • защищенный - доступен из пакета и подклассов в другом пакете. также

  • частный - доступен только из своего класса.

Вот лучшая версия таблицы, которая также включает столбец для модулей.

Java Access Modifiers

Пояснения

  • Член частный (i) - это Только, доступный в том же классе, в котором он объявлен.

  • Член с нет модификатора доступа (j) доступен только внутри классов в том же пакете.

  • Член защищенный (k) доступен во всех классах одного пакета и в подклассах других пакетов.

  • Член общественный (l) доступен для всех классов (если только он не находится в модуль, который не экспортирует пакет, в котором он объявлен).


Какой модификатор выбрать?

Модификаторы доступа - это инструмент, который поможет вам предотвратить случайное нарушение инкапсуляции (*). Спросите себя, хотите ли вы, чтобы этот член был чем-то внутренним по отношению к классу, пакету, иерархии классов или вообще не внутренним, и выберите соответствующий уровень доступа.

Примеры:

  • Поле long internalCounter, вероятно, должно быть закрытым, поскольку оно изменяемое и является деталью реализации.
  • Класс, который должен быть создан только в фабричном классе (в том же пакете), должен иметь конструктор, ограниченный пакетом, поскольку не должно быть возможности вызвать его напрямую извне пакета.
  • Внутренний метод void beforeRender(), вызываемый непосредственно перед рендерингом и используемый как перехватчик в подклассах, должен быть защищен.
  • Метод void saveGame(File dst), который вызывается из кода графического интерфейса пользователя, должен быть общедоступным.

(*) What is Encapsulation exactly?

Сразу скажу: есть много людей, у которых проблемы с различением красного / зеленого цветов. Таблицы, использующие схемы раскраски красный / зеленый (или желтый / оранжевый / ...) редко бывают "лучше" в чем-либо ;-)

GhostCat 11.10.2018 13:50

@GhostCat, я не согласен. Я думаю, что красный / зеленый интуитивно сочетается с «работает» / «не работает» для многих людей, т.е. это является лучше, чем многие альтернативы.

aioobe 14.11.2018 17:10
colourblindawareness.org/colour-blindness/… ... 8% дальтоников можно разделить примерно на 1% дейтеранопов, 1% протанопов, 1% протаномалов и 5% дейтераномальных. И поскольку я один из тех 50% из этих 5%, будьте уверены: красный / зеленый - отстой.
GhostCat 14.11.2018 17:13

@GhostCat Хорошо ... это большая часть населения, чем я ожидал. Я загрузил изображение в этот симулятор дальтонизма и протестировал все разные режимы. Даже в режиме монохромности / ахроматопсии разница в цвете разумная. Вы видите разницу или симулятор выключен? (Я по-прежнему считаю, что красный / зеленый очень интуитивно понятен для людей, видящих цвета.)

aioobe 14.11.2018 17:32

Я вижу разницу, но я также могу пройти половину тестов на дальтонизм, которые мы должны сделать в Германии для получения водительских прав ;-) ... но я думаю, что такой симулятор «достаточно хорош».

GhostCat 14.11.2018 17:40

Я запуталась с цветами

RMati 24.06.2019 08:26

Важно помнить, что эти модификаторы доступа применяются к классу, а не к объекту. Таким образом, objectA типа Chicken может получить доступ к частным свойствам objectB также типа Chicken, но только если код написан внутри класса Chicken.

Gilboot 27.06.2020 22:43

Модификаторы доступа в Java.

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

1. По умолчанию:

Доступно только для классов в одном пакете.

Например,

// Saved in file A.java
package pack;

class A{
  void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B{
  public static void main(String args[]){
   A obj = new A(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}

Этот доступ более ограничен, чем публичный и защищенный, но менее ограничен, чем частный.

2. Общественные

Доступен откуда угодно. (Глобальный доступ)

Например,

// Saved in file A.java

package pack;
public class A{
  public void msg(){System.out.println("Hello");}
}

// Saved in file B.java

package mypack;
import pack.*;

class B{
  public static void main(String args[]){
    A obj = new A();
    obj.msg();
  }
}

Output:Hello

3. Частный

Доступно только внутри одного класса.

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

class A{
  private int data = 40;
  private void msg(){System.out.println("Hello java");}
}

public class Simple{
  public static void main(String args[]){
    A obj = new A();
    System.out.println(obj.data); // Compile Time Error
    obj.msg(); // Compile Time Error
  }
}

4. Защищено

Доступен только классам в одном пакете и подклассам

Например,

// Saved in file A.java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}

Output: Hello

Enter image description here

Примечание: Это просто добавка принятого ответа.

Это связано с Java Модификаторы доступа.

От Модификаторы доступа Java:

A Java access modifier specifies which classes can access a given class and its fields, constructors and methods. Access modifiers can be specified separately for a class, its constructors, fields and methods. Java access modifiers are also sometimes referred to in daily speech as Java access specifiers, but the correct name is Java access modifiers. Classes, fields, constructors and methods can have one of four different Java access modifiers:

  • List item
  • private
  • default (package)
  • protected
  • public

Из руководств Управление доступом к членам класса:

Access level modifiers determine whether other classes can use a particular field or invoke a particular method. There are two levels of access control:

  • At the top level—public, or package-private (no explicit modifier).
  • At the member level—public, private, protected, or package-private (no explicit modifier).

A class may be declared with the modifier public, in which case that class is visible to all classes everywhere. If a class has no modifier (the default, also known as package-private), it is visible only within its own package

The following table shows the access to members permitted by each modifier.

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
║ 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     ║
╚═════════════╩═══════╩═════════╩══════════╩═══════╝

The first data column indicates whether the class itself has access to the member defined by the access level. As you can see, a class always has access to its own members. The second column indicates whether classes in the same package as the class (regardless of their parentage) have access to the member. The third column indicates whether subclasses of the class declared outside this package have access to the member. The fourth column indicates whether all classes have access to the member.

Access levels affect you in two ways. First, when you use classes that come from another source, such as the classes in the Java platform, access levels determine which members of those classes your own classes can use. Second, when you write a class, you need to decide what access level every member variable and every method in your class should have.

что именно представляет собой дополнение и почему это не редактирование существующего сообщения?

sehe 17.11.2016 18:39

дополнение - Модификаторы доступа. Почему не редактировать? Оставить принятый ответ неизменным по историческим причинам и дать свой ответ.

ישו אוהב אותך 18.11.2016 05:25

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

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

  • Когда вы приводите его в университетский городок, первое, что видите вы и ваш друг, - это статуя. Это означает, что любой, кто ходит по кампусу, может смотреть на статую без разрешения университета. Это делает статую ПУБЛИЧНЫЙ.

  • Затем вы хотите отвести друга к себе в общежитие, но для этого вам необходимо зарегистрировать его как посетителя. Это означает, что он получает пропуск (такой же, как у вас), чтобы попасть в различные здания на территории кампуса. Это сделает его карту доступа ЗАЩИЩЕННЫЙ.

  • Ваш друг хочет войти в сеть Wi-Fi кампуса, но у него нет для этого учетных данных. Единственный способ, которым он может выйти в Интернет, - это если вы поделитесь с ним своим логином. (Помните, что каждый студент, поступающий в университет, также имеет эти учетные данные). Это сделает ваши учетные данные как БЕЗ МОДИФИКАТОРА.

  • Наконец, ваш друг хочет прочитать ваш отчет об успеваемости за семестр, который размещен на веб-сайте. Однако у каждого студента есть свой личный логин для доступа к этому разделу веб-сайта кампуса. Это сделает эти учетные данные как ЧАСТНЫЙ.

Надеюсь это поможет!

Когда вы думаете о модификаторах доступа, просто думайте об этом так (применимо как к переменные, так и к методы):

public -> доступен отовсюду private -> доступен только в том же классе, где он объявлен

Теперь возникает путаница, когда дело касается default и protected.

default -> Ключевое слово модификатора доступа отсутствует. Это означает, что он доступен строго внутри пакета класса. Нигде вне этого пакета к нему можно получить доступ.

protected -> Чуть менее строгий, чем default, и, помимо тех же классов пакетов, к нему могут обращаться подклассы за пределами объявленного упаковка.

Все дело в инкапсуляция (или, как сказал Джо Филлипс, наименьшее знание).

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

Мы все используем модификаторы методов и членов, такие как private, public, ... но очень немногие разработчики делают одну вещь - логически используют пакеты для кода организовать.

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

Outside world -> Package (SecurityEntryClass ---> Package private classes)

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

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

  • общественный

    Если член класса объявлен с помощью public, то к нему можно получить доступ из любого места.

  • защищенный

    Если член класса объявлен с защищенным ключевым словом, то к нему можно получить доступ из тех же членов класса, вне членов класса в том же пакете и унаследованных членов класса. Если член класса защищен, то к нему НЕЛЬЗЯ получить доступ из внешнего класса пакета, если внешний упакованный класс не унаследован, т.е. расширяет другой суперкласс пакета. Но член защищенного класса всегда доступен для одних и тех же классов пакетов, НЕ имеет значения, унаследован ли тот же класс пакета или НЕ

  • дефолт

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

  • частный

    Если член класса объявлен с защищенным ключевым словом, то в этом случае он доступен ТОЛЬКО для тех же членов класса.

private-protected-public-perfect-analogy-for-the-variable-data-types

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

Примечание. Объявление членов данных со спецификатором частного доступа известно как сокрытие данных..

Источник: Спецификаторы доступа - частные, общедоступные и защищенные

Речь шла о Java, а не о C++.

Benoit 20.09.2019 11:57

@Benoit Но то, что я опубликовал, особенно изображения, не одинаковы для обоих: java и C++? Эти правила не применяются и для java? Благодарность

leonidaa 22.09.2019 13:31

В C++ модификаторов всего 3, а в java - 4.

Benoit 23.09.2019 12:15

аналогия хороша, но спецификатор доступа по умолчанию отсутствует,

mss 03.01.2020 12:54

OP задал вопрос: «В чем разница между общедоступным, защищенным, частным пакетом и частным в Java?»

JL_SO 10.04.2020 00:00

Мои два цента :)

частный:

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

переменная экземпляра -> доступен только в классе. Нет доступа вне класса.

частный пакет:

класс -> класс верхнего уровня может быть частным для пакета. Он может быть доступен только из того же пакета. Не из дополнительного пакета, не из внешнего пакета.

переменная экземпляра -> доступен из того же пакета. Не из дополнительного пакета, не из внешнего пакета.

защищено:

класс -> класс верхнего уровня не может быть защищен.

переменная экземпляра -> Доступно только в том же пакете или подпакете. Доступ к нему возможен только вне пакета при расширении класса.

общественность:

класс -> доступен из пакета / подпакета / другого пакета

переменная экземпляра -> доступен из пакета / подпакета / другого пакета

Вот подробный ответ

https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md

Доступ к Java изменяет то, что вы можете использовать

Модификатор доступа может применяться для class, field[About], method. Попробуйте получить доступ, создать подкласс или переопределить это.

  • Доступ к field или method осуществляется через class.
  • Наследование и Принцип открытости и закрытости.
    • Модификатор доступа наследника class (подкласса) может быть Любые.
    • Модификатор доступа преемника method (переопределить) должен быть такой же или расширить его

Класс верхнего уровня (область первого уровня) может быть public и default. Nested class[About] может иметь любой из них

package не претендует на иерархию пакетов

[Модификаторы быстрого доступа]

Спецификаторы доступа в Java: В java есть 4 спецификатора доступа: private, package-private (по умолчанию), protected и public в порядке возрастания доступа.

Частный: Когда вы разрабатываете какой-либо класс и хотите, чтобы член этого класса не отображался за пределами этого класса, вы должны объявить его закрытым. к закрытым членам можно получить доступ только в том классе, в котором они определены, то есть охватывающем классе. Доступ к закрытым членам можно получить по ссылке «this», а также по другим экземплярам класса, включающего эти члены, но только в пределах определения этого класса.

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

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

По сути, в одном пакете вы можете получить доступ к членам по умолчанию в экземпляре класса напрямую или по ссылке «this» в подклассах.

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

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

Пожалуйста, обрати внимание:

  1. Вы не сможете получить доступ к унаследованному защищенному члену Class1 в Class2, если вы попытаетесь получить к нему доступ в явном экземпляре Class1, хотя в нем это передается по наследству.
  2. Когда вы пишете другой класс Class3 в том же / другом пакете который расширяет Class2, защищенный член из Class1 будет доступен по этой ссылке, а также по явному экземпляру Class3. Это будет быть верным для любой расширенной иерархии, т.е. защищенного члена будет по-прежнему доступен по этой ссылке или экземпляру расширенного класс. Обратите внимание, что в Class3, если вы создаете экземпляр Class2, тогда вы не сможете получить доступ к защищенному члену из Class1, хотя это передается по наследству.

Итог: К защищенным членам можно получить доступ в других пакетах, только если некоторый класс из этого другого пакета расширяет класс, включающий этот защищенный член, а защищенный член доступен по ссылке «this» или явным экземплярам расширенного класса в пределах определения расширенного класса.

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

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

Differences between public, private, default and protected access modifiers

Это изображение поможет вам легко понять основные различия между модификаторами доступа public, private, protected и default. Модификатор по умолчанию применяется автоматически, если вы не объявляете в своем коде модификаторы доступа ant.

Для большей наглядности no modifier == package private | package protected

ahmednabil88 18.12.2020 23:56

Это хорошая демонстрация

Mushfiqur Rahman Abir 15.03.2021 18:05

Другие вопросы по теме