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

3537
intrepion 18 Окт 2008 в 23:53
184
private скрывается от других классов в пакете. public предоставляется классам вне пакета. protected - это версия public, ограниченная только подклассами.
 – 
Museful
13 Фев 2013 в 13:56
103
- Нет ; в отличие от C ++, в Java protected делает метод доступным также из всего пакета. Эта глупость в модели видимости Java нарушает цель protected.
 – 
Nicolas Barbulesco
21 Авг 2013 в 13:51
40
Он доступен из всего пакета, с protected или без него. В качестве модификатора доступа все, что делает protected, - это предоставление доступа подклассам вне пакета.
 – 
Museful
14 Мар 2014 в 14:59
17
- ну, это то, что сказал Николас ... и вы просто повторяете это сейчас. Первоначально вы сказали, что protected - и я цитирую - «это версия public, ограниченная только подклассами», что неверно, по вашему собственному признанию, поскольку protected также разрешает доступ через весь пакет (следовательно, он не ограничить доступ к подклассам.)
 – 
luis.espinal
7 Апр 2014 в 17:45
14
Я также согласен с Николасом в том, что режим защищенного доступа в Java - это идиотизм. Случилось так, что Java объединила квалификаторы горизонтального (решетчатого) и вертикального ограничения доступа. Область действия по умолчанию - это ограничение по горизонтали / решетке, при этом решетка является пакетом. Public - еще одно горизонтальное ограничение, где решетка - это весь мир. Частные и (C ++) защищенные - вертикальные. Было бы лучше, если бы у нас был сквозной доступ, скажем, protected-package для тех редких случаев, когда он нам действительно нужен, оставив protected эквивалентным защищенной версии C ++.
 – 
luis.espinal
7 Апр 2014 в 17:53

29 ответов

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

Частный

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

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

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

Защищено

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

Общественного

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

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

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

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

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

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

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

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

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

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

526
R.Kabir 20 Дек 2021 в 03:53
27
Друзья -> «Чем меньше вы об этом знаете, тем лучше» ---> Это дает выборочную видимость, которая по-прежнему превосходит конфиденциальность пакетов. В C ++ это имеет свое применение, потому что не все функции могут быть функциями-членами, а друзья лучше, чем общедоступные. Конечно, есть опасность злоупотребления злыми умами.
 – 
Sebastian Mach
7 Июн 2011 в 14:13
33
Также следует отметить, что «защищенный» в C ++ имеет другое значение - защищенный метод фактически является закрытым, но все же может вызываться из наследующего класса. (В отличие от Java, где он может вызываться любым классом в одном пакете.)
 – 
Rhys van der Waerden
2 Окт 2011 в 16:34
9
C # в этом аспекте такой же, как C ++. Мне кажется довольно странным, что Java не позволяет объявлять член, доступный для подкласса, но не для всего пакета. Для меня это как бы вверх ногами - пакет шире, чем дочерний класс!
 – 
Konrad Morawski
15 Окт 2013 в 21:36
15
Пакет IMHO имеет меньший объем, чем подкласс. Если вы не объявили свой класс final, пользователи должны иметь возможность создавать подклассы, поэтому защита java является частью вашего опубликованного интерфейса. OTOH, пакеты неявно разрабатываются одной организацией: например, com.mycompany.mypackage. Если ваш код объявляется в моем пакете, вы неявно объявляете себя частью моей организации, поэтому мы должны общаться. Таким образом, пакет публикуется для меньшей / более доступной аудитории (люди в моей компании), чем подкласс (люди, которые расширяют мой объект), и поэтому считается более низкой видимостью.
 – 
Eponymous
23 Май 2014 в 00:37
2
friend хорошо подходит для определения особых отношений между классами. Во многих случаях при правильном использовании он обеспечивает превосходную инкапсуляцию. Например, он может использоваться привилегированным классом фабрики для внедрения внутренних зависимостей в сконструированный тип. У него плохая репутация, потому что люди, которые не заботятся о правильной поддержке хорошо спроектированной объектной модели, могут злоупотреблять ею, чтобы облегчить свою рабочую нагрузку.
 – 
Dennis
8 Дек 2014 в 13:05

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

enter image description here


Пояснения

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

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

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

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


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

( * )

Примеры:

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

(*) Что такое инкапсуляция?

504
aioobe 17 Авг 2022 в 21:30
23
Сразу скажу: есть много людей, у которых проблемы с различением красного / зеленого цветов. Таблицы с красными / зелеными (или желтыми / оранжевыми / ...) схемами окраски редко бывают "лучше" в чем-либо ;-)
 – 
GhostCat
11 Окт 2018 в 13:50
8
@GhostCat, я не согласен. Я думаю, что красный / зеленый интуитивно сочетается с «работает» / «не работает» для многих людей, т.е. это лучше, чем многие альтернативы.
 – 
aioobe
14 Ноя 2018 в 17:10
12
colourblindawareness.org/colour-blindness/….. 8% дальтоников можно разделить примерно на 1% дейтеранопов, 1% протанопов, 1% протаномных и 5% дейтераномных . И я один из них. 50% из этих 5%, будьте уверены: красный / зеленый - отстой.
 – 
GhostCat
14 Ноя 2018 в 17:13
7
Хорошо .. это большая часть населения, чем я ожидал. Я загрузил изображение в этот симулятор цветовой слепоты и протестировал все режимы. Даже в режиме монохромности / ахроматопсии разница в цвете разумная. Вы видите разницу или симулятор выключен? (Я по-прежнему считаю, что красный / зеленый очень интуитивно понятен для людей, видящих цвета.)
 – 
aioobe
14 Ноя 2018 в 17:32
5
Я вижу разницу, но я также могу пройти половину тестов на дальтонизм, которые мы должны сделать в Германии для получения водительских прав ;-) ... но я думаю, что такой симулятор «достаточно хорош».
 – 
GhostCat
14 Ноя 2018 в 17:40
____________________________________________________________________
                | 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         |       ✔       |     ✘     |       ✘       |   ✘    
____________________________________________________________________
221
Clark Kent 24 Дек 2019 в 14:23
2
Стоит выразить словами: «Модификатор Protected делает объект доступным для других пакетов, тогда как модификатор default / no ограничивает доступ к тому же пакету»
 – 
vanguard69
15 Авг 2016 в 19:53
2
@ vanguard69, модификатор protected делает отмеченный объект (класс, метод или поле) доступным какому-то другому классу в каком-то другом пакете , только если указанный другой класс является подклассом класса, в котором объявлена ​​эта protected - отмеченная вещь .
 – 
Abdull
15 Авг 2016 в 21:14

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

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

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

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

174
kvantour 24 Июл 2018 в 17:45
4
@RuchirBaronia, "world" = весь код в приложении, независимо от того, где он находится.
 – 
Andrejs
26 Фев 2016 в 22:12
Хотя информация в этом ответе может быть полезной, вопрос заключался не в том, должны ли мы начать с объявления всего приватным, а затем раскрывать что-то, если нам нужно это сделать.
 – 
nbro
5 Апр 2022 в 13:39

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

Доступ "по умолчанию" (определяемый отсутствием ключевого слова) также называется package-private < / strong>. Исключение: в интерфейсе отсутствие модификатора означает открытый доступ; модификаторы, отличные от общедоступных, запрещены. Константы перечисления всегда открыты.

Резюме

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

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

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

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

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

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

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

Порядок

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

общедоступный> защищенный> частный пакет> частный

Это означает, что 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

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

120
Community 23 Май 2017 в 15:34
2
«Модификаторы, отличные от общедоступных, запрещены» - начиная с Java 9 это уже не так: интерфейсы также могут иметь частные методы.
 – 
MC Emperor
25 Авг 2018 в 23:34

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

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

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

  • (D) irect (вызов из метода внутри того же класса или с помощью синтаксиса this).
  • (R) ссылка (вызов метода с использованием ссылки на класс или синтаксиса с точкой).
  • (I) наследование (через создание подклассов).

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

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+
99
Hoa Nguyen 25 Июн 2019 в 18:55

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

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

Наиболее неправильно понимаемый модификатор доступа в 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):

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

      пакет sonpackage;   публичный класс сын расширяет отца  {      public void sonMethod()      {          это.foo();          супер.foo();      }  }    
    3. Для ссылки, тип которой относится к тому же классу:

      пакет   Отец публичного класса  {      public void FatherMethod(Father f)      {          f.foo();  // действителен, даже если foo() является приватным      }  }   -------------------------------------------   пакетный пакет;   публичный класс сын расширяет отца  {      public void sonMethod(Son s)      {          s.foo();      }  }    
    4. Для ссылки, тип которой является родительским классом и находится внутри пакета, в котором определено foo() (fatherpackage) [Это может быть включено в контекст нет. 1]:

      пакет   публичный класс сын расширяет отца  {      public void sonMethod(Father f)      {          f.foo();      }  }  
  • Следующие ситуации недопустимы.

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

      пакет sonpackage;   публичный класс сын расширяет отца  {      public void sonMethod(Father f)      {          f.foo();  // ошибка компиляции      }  }    
    2. Не-подкласс внутри пакета подкласса (подкласс наследует защищенные элементы от своего родителя и делает их закрытыми для не-подклассов):

      пакет sonpackage;   открытый класс SomeClass  {      public void someMethod(Son s) выдает исключение      {          s.foo();  // ошибка компиляции      }  }  
52
Eng.Fouad 14 Сен 2017 в 22:35
Object#clone() - это пример члена protected.
 – 
Eng.Fouad
16 Ноя 2013 в 00:08
В чем разница между выполнением super.foo() и первой недопустимой ситуацией f.foo()?
 – 
cst1992
28 Окт 2017 в 12:18
2
Это сбивает с толку, но см. Спецификацию языка Java 6.6.2: «Доступ к защищенному члену или конструктору объекта может быть получен извне пакета, в котором он объявлен, только кодом, который отвечает за реализацию этого объекта». В super.foo () ссылка «super» «непосредственно отвечает за реализацию», а ссылка «f» - нет. Почему? Потому что вы можете быть на 100% уверены, что «super» относится к типу «Отец», но не к «f»; во время выполнения это может быть какой-то другой подтип отца. См. docs.oracle.com / javase / specs / jls / se9 / html /…
 – 
skomisa
30 Янв 2018 в 20:55
1
Приятно читать ответ человека, который понимает protected. К сожалению, все остальные ответы на этой странице, которые определяют protected, немного ошибаются.
 – 
Dawood ibn Kareem
11 Июл 2018 в 09:20
Это не то, что говорится на официальном сайте Oracle: «Модификатор protected указывает, что член может быть доступен только в его собственном пакете (как с package-private) и, кроме того, подклассом его класса в другом пакете." - docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol .html
 – 
Marco Sulla
6 Июл 2021 в 10:47

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

21
Joe Phillips 19 Окт 2008 в 00:00

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

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

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

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

20
Peter Mortensen 12 Ноя 2017 в 01:26

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

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

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

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

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

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

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

Личное: это может быть доступ в том же классе.

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

17
Peter Mortensen 12 Ноя 2017 в 01:28

Модификаторы доступа в 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();
  }
}

Выход: Здравствуйте

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();
  }
}

Вывод: Привет

Enter image description here

17
Community 20 Июн 2020 в 12:12

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

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

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

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

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

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(){
    }

}
14
Peter Mortensen 12 Ноя 2017 в 01:32
  • общедоступный - доступен из любой точки приложения.

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

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

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

13
Alex Weitz 16 Мар 2016 в 18:31

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

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

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

11
Peter Mortensen 12 Ноя 2017 в 01:23
Просто добавьте следующее: «Как только дочерний элемент получает доступ к защищенному члену родительского класса, он становится закрытым (или, скорее, я бы сказал, специальным закрытым членом, который может быть унаследован подклассами подкласса) членом подкласса».
 – 
Anand
27 Окт 2012 в 22:55

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

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

10
Peter Mortensen 12 Ноя 2017 в 01:22

Differences between public, private, default and protected access modifiers

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

6
Mushfiqur Rahman Abir 12 Сен 2020 в 10:33
2
Для большей ясности no modifier == package private | package protected
 – 
ahmednabil88
18 Дек 2020 в 23:56

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

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

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

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

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

5
richa_v 30 Июл 2014 в 07:51
Default не является модификатором доступа, а два других написаны с ошибками.
 – 
user207421
24 Сен 2016 в 06:13

Примечание. Это просто дополнение к принятому ответу.

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

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

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

  • Пункт списка
  • частный
  • по умолчанию (пакет)
  • защищенный
  • общественности

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

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

  • На верхнем уровне - общедоступный или частный для пакета (без явного модификатора).
  • На уровне члена - общедоступный, частный, защищенный или частный для пакета (без явного модификатора).

Класс может быть объявлен с модификатором public, и в этом случае этот класс будет виден всем классам повсюду. Если у класса нет модификатора (по умолчанию, также известного как package-private), он виден только в его собственном пакете.

В следующей таблице показан доступ к членам, разрешенный каждым модификатором.

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

Первый столбец данных указывает, имеет ли сам класс доступ к члену, определенному уровнем доступа. Как видите, класс всегда имеет доступ к своим собственным членам. Второй столбец указывает, имеют ли классы в том же пакете, что и класс (независимо от их происхождения), доступ к члену. Третий столбец указывает, имеют ли подклассы класса, объявленного вне этого пакета, доступ к члену. Четвертый столбец показывает, все ли классы имеют доступ к члену.

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

5
ישו אוהב אותך 17 Ноя 2016 в 08:05
1
Что именно представляет собой дополнение и почему это не редактирование существующего сообщения?
 – 
sehe
17 Ноя 2016 в 18:39
Дополнение - Модификаторы доступа. Почему не редактировать? Оставить принятый ответ неизменным по историческим причинам и дать свой ответ.
 – 
ישו אוהב אותך
18 Ноя 2016 в 05:25

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

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

  • Когда вы приводите его в университетский городок, первое, что видите вы и ваш друг, - это статуя. Это означает, что любой, кто ходит по кампусу, может смотреть на статую без разрешения университета. Это делает статую ОБЩЕСТВЕННОЙ .

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

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

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

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

5
Greedy Coder 6 Апр 2017 в 07:09

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

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

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

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

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

3
Pritam Banerjee 27 Июн 2017 в 05:38

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

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

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

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

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

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

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

2
Christophe Roussy 31 Июл 2018 в 14:27

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

частный:

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

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

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

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

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

защищено:

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

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

общедоступный:

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

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

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

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

2
Mudassar 22 Окт 2019 в 19:25
  • общественности

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

  • защищенный

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

  • дефолт

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

  • частный

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

-1
Vipul Verma 20 Сен 2019 в 01:34

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

Использование модификатора закрытого доступа в: - Только тот же класс

Использование модификатора доступа по умолчанию в: - Только тот же класс / те же подклассы пакета

Использование модификатора защищенного доступа: - в одном классе / в одном и том же подклассе пакета / в одном и том же пакете без - в подклассах / в разных подклассах пакетов

Модификатор открытого доступа используется в: — мы можем использовать где угодно (тот же класс / те же подклассы пакета / тот же пакет не-подклассы / разные подклассы пакета / разные пакеты не-подклассы)

-1
Tiyus98 7 Июл 2022 в 10:02
Как сейчас написано, ваш ответ неясен. Пожалуйста, отредактируйте, чтобы добавить дополнительные сведения, которые помогут другим понять, как это отвечает на заданный вопрос. Дополнительную информацию о том, как писать хорошие ответы, можно найти в справочном центре.
 – 
ethry
6 Июл 2022 в 09:43

Спецификаторы доступа в Java: в Java есть 4 спецификатора доступа, а именно частный, частный для пакета (по умолчанию), защищенный и открытый в порядке возрастания доступа.

Личное : Когда вы разрабатываете какой-либо класс и хотите, чтобы член этого класса не отображался за пределами этого класса, вы должны объявить его закрытым. к закрытым членам можно получить доступ только в том классе, в котором они определены, то есть охватывающем классе. Доступ к закрытым членам можно получить по ссылке "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' или явным экземплярам расширенного класса внутри определение расширенного класса.

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

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

-2
Tushar Baviskar 2 Мар 2020 в 14:23

Используйте private, если вы не хотите, чтобы ваши переменные/методы/классы были видны за пределами этого класса. используйте protected, если вы хотите, чтобы только дочерние элементы этого класса могли использовать эти переменные. используйте public, если вы хотите, чтобы переменная/класс/метод были доступны из любого места. используйте package-private, если вы хотите, чтобы ваши переменные/классы/методы использовались только внутри этого пакета.

-2
Yogesh Sharma 10 Фев 2022 в 18:17

< Сильный > Частный

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

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

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

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

Примечание

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


< Сильный > Защищенный

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

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

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

Примечание

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


< Сильный > Public

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

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

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

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

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


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

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

  • В одном пакете

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

Примечание

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

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

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

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

30
Community 23 Май 2017 в 14:47

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

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

enter image description here

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

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

2
leonidaa 20 Сен 2019 в 10:28
1
Речь шла о Java, а не о C ++.
 – 
Benoit
20 Сен 2019 в 11:57
1
Но то, что я опубликовал, особые изображения, не одинаковы для обоих: java и c ++? Эти правила не применяются и для java? Благодарность
 – 
leonidaa
22 Сен 2019 в 13:31
2
В C ++ модификаторов всего 3, а в java - 4.
 – 
Benoit
23 Сен 2019 в 12:15
1
Аналогия хороша, но спецификатор доступа по умолчанию отсутствует,
 – 
mss
3 Янв 2020 в 12:54
1
OP задал вопрос: «В чем разница между общедоступным, защищенным, частным пакетом и частным в Java?»
 – 
JL_SO
10 Апр 2020 в 00:00