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

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

36 ответов

Решение

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

            │ Класс │ Пакет │ Подкласс │ Подкласс │ Мир
            Same │ │ (тот же pkg)│(diff pkg)│ 
────────────┼───────┼─────────┼──────────┼──────────┼────────
публичный │ + │ + │ + │ + │ +     
────────────┼───────┼─────────┼──────────┼──────── ──┼────────
защищенный │ + │ + │ + │ + │         
────────────┼───────┼─────────┼──────────┼──────── ──┼────────
без модификатора │ + │ + │ + │ │    
────────────┼───────┼─────────┼──────────┼──────── ──┼────────
личное │   +   │         │          │          │    

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

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

Частный

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

Пакет Приват

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

защищенный

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

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

Каждый может это увидеть.

опубликованный

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

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

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

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

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

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

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

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

Вот лучшая версия таблицы. (Будущее с колонкой для модулей.)

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

Пояснения

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

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

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

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


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

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

Примеры:

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

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

                | 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         |       ✔       |     ✘     |       ✘       |   ✘    

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

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

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

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

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

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

Резюме

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

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

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

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

Только для классов в верхней области видимости public и пакет-частный разрешены. Этот выбор дизайна, вероятно, потому что 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

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

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

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

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

  • (D) irect (вызывается из метода внутри того же класса).
  • (R) eference (вызывать метод, используя ссылку на класс или через синтаксис "точка").
  • (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   |
+—————————————————+————————————+———————————+

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

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

Самый неправильно понятый модификатор доступа в 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
          }
      }
      

Частный

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

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

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

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

Заметка

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


защищенный

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

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

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

Заметка

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


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

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

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

  • Разные пакеты

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

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


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

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

  • В рамках одного пакета

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

Заметка

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

Похожие ответы

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

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

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

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

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

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

package не применяется к иерархии пакетов

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

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

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

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

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

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

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

Выход: привет

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

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

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

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

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

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

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

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

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

Видна на упаковке. По умолчанию. Модификаторы не нужны.

Доступно только для класса (личное).

Видимый миру (публичный).

Доступен для пакета и всех подклассов (защищен).

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

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

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

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

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

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

Пример:

public void cal(){

}

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

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

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

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

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

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

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

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

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

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

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

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

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

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

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

  • Типы, не являющиеся членами (то есть классы, перечисления, интерфейсы и типы аннотаций, не объявленные внутри другого типа), по умолчанию являются закрытыми для пакета. ( JLS §6.6.1)

  • Члены класса и конструкторы по умолчанию закрыты для пакета. ( JLS §6.6.1)

  • Конструкторы Enum по умолчанию являются закрытыми. (Действительно, перечислители-перечислители должны быть закрытыми, и попытка сделать их общедоступными или защищенными является ошибкой). Константы перечисления являются общедоступными и не допускают какого-либо спецификатора доступа. Другие члены перечислений по умолчанию закрыты для пакета. ( JLS §8.9)

  • Все члены интерфейсов и типов аннотаций являются открытыми по умолчанию. (Действительно, члены интерфейсов и типы аннотаций должны быть открытыми, и попытка сделать их частными или защищенными является ошибкой.) ( JLS §9.3–9.5)

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

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

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

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

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

  • Видна на упаковке. по умолчанию. Модификаторы не нужны.
  • Доступно только для класса;частный
  • Видимый миру;общедоступный.
  • Видимый для пакета и всех подклассов;защищен.

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

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

Примечание: это всего лишь дополнение к принятому ответу.

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

Из модификаторов доступа Java:

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

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

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

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

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

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

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

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

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

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

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

  • Ваш друг хочет войти в кампус Wi-Fi, но не имеет никаких учетных данных для этого. Единственный способ, которым он может выйти в Интернет, - это если вы поделитесь с ним своим логином. (Помните, что каждый студент, который поступает в университет, также имеет эти учетные данные). Это сделало бы ваши учетные данные для входа без модификатора.

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

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

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

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

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

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

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

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

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

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

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

частный:

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

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

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

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

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

защищено:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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