Вопрос

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

Это было полезно?

Решение

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

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

 + : accessible         blank : not accessible

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

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

Частный

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

Личный пакет

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

Protected

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

Public

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

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

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

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

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

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

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

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

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

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

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

Java Access Modifiers

Объяснения

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

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

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

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


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

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

Примеры:

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

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

                | 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, запрещены.Константы Enum всегда являются общедоступными.

Краткие сведения

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

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

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

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

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

Некоторые сопутствующие вопросы:

Как эмпирическое правило:

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

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

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

В оченькратце

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

Частное

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

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

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

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

Примечание

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


Защищенный

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

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

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

Примечание

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


Публичный

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

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

  • Разные Упаковки

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

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


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

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

  • В рамках одних и тех же Пакетов

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

Примечание

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Виден только для класса (Частное).

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

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

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

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:

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

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

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

Пример:

public void cal(){

}

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

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

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

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

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

На этой странице хорошо написано о модификаторе защищенного доступа и доступа по умолчанию

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

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

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

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

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

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

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

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

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

<Ол>
  • Класс может быть общедоступным или по умолчанию
  • Члены класса могут быть открытыми, защищенными, стандартными или закрытыми.
  • Личное недоступно за пределами класса По умолчанию доступен только в пакете. Защищено как в пакете, так и в любом классе, который его расширяет. Общественность открыта для всех.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top