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

2722

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

  • 141
    private скрывает от других классов в пакете. public выставляет классы вне пакета. protected - это версия public доступная только подклассам.
  • 79
    @Tennenrishin - Нет; в отличие от C ++, в Java protected метод делает метод также доступным из всего пакета. Эта глупость в модели видимости Java нарушает цель protected .
Показать ещё 15 комментариев
Теги:
private
public
access-modifiers
protected

27 ответов

5232
Лучший ответ

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

            │ C │ P │ Subclass │ Subclass │ W │
            │ l │ a │(same pkg)│(diff pkg)│ o │
            │ a │ c │          │          │ r │
            │ s │ k │          │          │ l │
            │ s │ a │          │          │ d │
            │   │ g │          │          │   │
            │   │ e │          │          │   │
────────────┼───+───┼──────────┼──────────┼───┼
public      │ + │ + │    +     │     +    │ + │
────────────┼───────┼──────────┼──────────┼───┼
protected   │ + │ + │    +     │     +    │   │
────────────┼───────┼──────────┼──────────┼───┼
no modifier │ + │ + │    +     │          │   │
────────────┼───────┼──────────┼──────────┼───┼
private     │ + │   │          │          │   │

 + : accessible         blank : not accessible
  • 11
    Если вы пытаетесь получить доступ к защищенному методу или переменной экземпляра в том же классе, но в объекте, который не является вашим, как в случае .equals (Klass var), это сработает?
  • 6
    Поля по умолчанию видны в подклассах, если подклассы находятся в том же пакете, что и их родительский класс.
Показать ещё 17 комментариев
416

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

Частный

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

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

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

Protected

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

Public

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

Published

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

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

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

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

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

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

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

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

  • 19
    friends -> «Чем меньше вы знаете об этом, тем лучше» ---> Это обеспечивает выборочную видимость, которая по-прежнему превосходит конфиденциальность пакета. В C ++ он имеет свое применение, потому что не все функции могут быть функциями-членами, и друзья лучше, чем публичные публикации. Конечно, существует опасность злоупотребления злыми умами.
  • 26
    Следует также отметить, что «защищенный» в C ++ имеет другое значение - защищенный метод является по сути закрытым, но все же может вызываться из наследующего класса. (В отличие от Java, где он может вызываться любым классом в том же пакете.)
Показать ещё 7 комментариев
336

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

Изображение 1307

Пояснения

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

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

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

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


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

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

Примеры:

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

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

  • 1
    Просто скажу: есть много людей, у которых есть проблемы с различением красной / зеленой окраски. Таблицы, использующие красные / зеленые (или желтые / оранжевые / ...) схемы окраски, редко бывают «лучше» в чем-либо ;-)
  • 0
    @ GhostCat, я не согласен. Я думаю , что красный / зеленый Выравнивает интуитивно с «работой» / «не работает» для многих людей, то есть лучше , чем у многих альтернатив.
Показать ещё 3 комментария
185
                | 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         |              |     ✘     |       ✘       |   ✘    
  • 1
    Стоит выразить словами: «Защищенный модификатор делает объект доступным для других пакетов, тогда как default / no-modifier ограничивает доступ к тому же пакету»
  • 1
    @ vanguard69, protected модификатор делает помеченную вещь (класс, метод или поле) доступной для какого-либо другого класса в каком-то другом пакете только в том случае, если другой класс является подклассом класса, в котором объявлена protected помеченная вещь .
Показать ещё 4 комментария
142

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

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

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

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

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

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

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

Резюме

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

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

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

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

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

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

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

Заказ

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

public > protected > package-private > private

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

Примечания

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

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

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

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

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

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

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

  • 0
    «модификаторы, отличные от public, запрещены» - с Java 9 это уже не так: интерфейсы также могут иметь закрытые методы.
72

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

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

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

  • (D) direct (вызов из метода внутри одного класса).
  • (R) (вызов метода с использованием ссылки на класс или синтаксис "точка").
  • (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   |
+—————————————————+————————————+———————————+
  • 0
    Этот ответ заслуживает большего количества голосов.
44

В очень короткие

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

Самый непонятый модификатор доступа в 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() можно вызвать в четырех контекстах:

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

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

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
      
    • В ссылке, тип которой является одним и тем же классом:

      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();
          }
      }
      
    • В ссылке, тип которой является родительским классом, и находится внутри пакета, где foo() определен (fatherpackage) [Это может быть включено внутри контекста no. 1]:

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

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

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

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }
      
  • 0
    Object#clone() является примером protected члена.
  • 0
    В чем разница между выполнением super.foo() и первой f.foo() ситуацией f.foo() ?
Показать ещё 2 комментария
27

Частный

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

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

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

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

Примечание

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

Защищенный

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

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

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

Примечание

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

<ч/" >

Public

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

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

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

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

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

<ч/" >

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

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

  • Внутри тех же пакетов

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

Примечание

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

Ответы на вопросы

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

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

17

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

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

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

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

15

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

13

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

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

Изображение 1308

13

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

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

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

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

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

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

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

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

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

11
  • общедоступный - доступен из любого места приложения.

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

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

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

11

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

Только для класса (частный).

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

Видимый для пакета и всех подклассов (protected).

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

String name = "john";

public int age(){
    return age;
}

Частный приватный модификатор доступа:

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

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

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

Примеры:

Public class Details{

    private String name;

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

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

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

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

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

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

Пример:

public void cal(){

}

Защищенный модификатор доступа - защищен:

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

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

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

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}
10

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

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

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

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

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

  • 4
    А затем, просто чтобы запутать новичков, в интерфейсные методы в Java 8 был добавлен великолепный новый модификатор по default :)
9

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

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

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

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

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

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

6

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

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

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

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

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

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

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

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

  • 1
    Что именно является дополнением, и почему это не редактирование существующего поста?
  • 0
    Дополнение - Модификаторы доступа. Почему бы не редактировать? Сохранить принятый ответ без изменений для исторической пользы и дать мой ответ.
6
  • Видимый для пакета. по умолчанию. Модификаторы не нужны.
  • Только для класса private.
  • Видно миру; общедоступный.
  • Видимый для пакета и всех подклассов защищенный.

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

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

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

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

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

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

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

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

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

5

Public Protected Default и private - модификаторы доступа.

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

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

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

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

  • 0
    Default это не модификатор доступа, а два других написаны с ошибками.
4

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

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

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

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

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

3
 Default: When no access modifier is specified for a class , method or data 
 member – It is said to be having the default access modifier by default.
 The data members, class or methods which are not declared using any access 
 modifiers i.e. having default access modifier are accessible only within 
 the same package.



 Private: The private access modifier is specified using the keyword private.
 The methods or data members declared as private are accessible only within 
 the class in which they are declared.
 Any other class of same package will not be able to access these members.
 Classes or interface can not be declared as private.


 protected: The protected access modifier is specified using the keyword 
 protected.
 The methods or data members declared as protected are accessible within same 
 package or sub classes in different package.


 public: The public access modifier is specified using the keyword public.
 The public access modifier has the widest scope among all other access 
 modifiers.
 Classes, methods or data members which are declared as public are accessible 
 from every where in the program. There is no restriction on the scope of a 
 public data members.
2

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

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

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

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

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

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

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

-2

public → можно получить доступ везде

private → может быть доступ только к одному классу

protected → может иметь доступ к тому же классу, тому же подклассу пакета, другому подклассу пакета и тому же пакету другого класса

по умолчанию → может быть доступ к тому же классу, тому же подклассу пакета и тому же пакету другого класса

Ещё вопросы

Сообщество Overcoder
Наверх
Меню