В чем разница между public, protected, package-private и private на Java?

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

25 ответов


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

            │ Class │ Package │ Subclass │ Subclass │ World
            │       │         │(same pkg)│(diff pkg)│ 
────────────┼───────┼─────────┼──────────┼──────────┼────────
public      │   +   │    +    │    +     │     +    │   +     
────────────┼───────┼─────────┼──────────┼──────────┼────────
protected   │   +   │    +    │    +     │     +    │         
────────────┼───────┼─────────┼──────────┼──────────┼────────
no modifier │   +   │    +    │    +     │          │    
────────────┼───────┼─────────┼──────────┼──────────┼────────
private     │   +   │         │          │          │    

+ : accessible
blank : not accessible

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

частная

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

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

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

защищенный

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

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

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

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

видимый вне кода I control. (Хотя это не синтаксис Java, это важно для этого обсуждения).

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

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

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

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

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

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

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


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

Java Access Modifiers

объяснениями

  • A частная член только доступно в том же классе, что и объявлено.

  • член нет доступа модификатор доступно только в классах в то же пакет.

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

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


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

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

примеры:

  • поле long internalCounter вероятно, должен быть частным, так как он изменяемый и деталь реализации.
  • класс, который должен быть создан только на заводе класс (в том же пакете) должен иметь конструктор с ограниченным пакетом, поскольку его нельзя вызывать непосредственно из-за пределов пакета.
  • внутренний void beforeRender() метод, вызываемый непосредственно перед рендерингом и используемый в качестве крючка в подклассах, должен быть защищен.
  • A 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 при переопределении, чтобы вещи не ломались при рефакторинге.


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

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

резюме

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

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

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

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

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

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

по теме: Доступность Класса Java

ордер

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

public > protected > package-private > private

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

Примечания

  • класса are разрешен доступ к частным членам других объектов того же класс. точнее, метод класса C может получить доступ к частным членам C на объектах любого подкласса C. Java не поддерживает ограничение доступа по экземпляру, только по классу. (Сравните с Scala, которая поддерживает его с помощью private[this].)
  • вам нужен доступ к конструктору для создания объекта. Таким образом, если все конструкторы являются частными, класс может быть построен только кодом, живущим в классе (обычно статическими заводскими методами или статическими инициализаторами переменных). Аналогично для package-private или защищенных конструкторов.
    • только наличие частных конструкторов также означает, что класс не может быть подклассом извне, так как 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

некоторые вопросы:


Как правило:

  • частная: объем класс.
  • по умолчанию (или ): объем упаковки.
  • защищенный: объем пакета + ребенок (как пакета, но мы можем расширить его из разных пакетов). Защищенный модификатор всегда сохраняет связь "родитель-потомок".
  • общественные: везде.

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

  • (D) irect (вызов из метода внутри того же класса).
  • (Р)eference (вызовите метод, используя ссылку на класс, или с помощью синтаксиса" точка").
  • (I) nheritance (через наследование).

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

+—-———————————————+————————————+———————————+
|                 |    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: доступно для классов одного и того же пакета и подклассов, находящихся в любом пакете.
  • default (модификатор не указан): доступно для классов одного и того же пакета.
  • private: доступно только в одном классе.

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

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

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
    
  • давайте добавим защищенный метод foo() to 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) [это может быть включено в контекст no. 1]:

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

    1. по ссылке, тип которой является родительским классом, и это за пределами пакета, где foo() is определено (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.

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

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

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


по умолчанию -нет сайта:

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

  • в тех же пакетах

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

Примечание

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

Соответствующие Ответы

ссылки

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


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


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

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

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

Public: доступно для класса, пакета (все) и подклассов... Короче говоря, везде.


модификаторы доступа в 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. Публика

можно получить доступ из любого места. (Глобальный Access)

например,

// 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


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

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

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

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

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

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

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

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

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


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

видимый только классу (частная).

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

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

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

String name = "john";

public int age(){
    return age;
}

модификатор частного доступа-private:

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

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

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

примеры:

Public class Details{

    private String name;

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

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

модификатор публичного доступа-public:

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

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

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

пример:

public void cal(){

}

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

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

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

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

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

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

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

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

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


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

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

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

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

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


эта страница хорошо пишет о модификаторе доступа protected & default

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

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


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

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


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

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

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

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

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

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

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

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

С управление доступом к членам a Класс!--9--> инструкции:

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

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

класс может быть объявлен с модификатором общественность, и в этом случае класс виден всем классам повсюду. Если класс не имеет никакого модификатора (по умолчанию, также известный как 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 Protected Default и private являются модификаторами доступа.

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

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

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

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


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

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

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

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

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

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

надеюсь, что это помогает!


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

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

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

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

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


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

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

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

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

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

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

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