Is & ldquo; protected & rdquo; модификатор бесполезен? [Дубликат]

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

== возвращает true, если оба объекта (NOT TALKING OF PRIMITIVES) указывают на экземпляр SAME. .equals() возвращает true, если два объекта содержат одни и те же данные equals() Versus == в Java

Это может вам помочь.

2624
задан entpnerd 18 November 2017 в 01:42
поделиться

23 ответа

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

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

+ : accessible
blank : not accessible
4674
ответ дан Mahozad 15 August 2018 в 19:47
поделиться
  • 1
    Если вы пытаетесь получить доступ к защищенному методу или переменной экземпляра в том же классе, но на объекте, который не вы, как в случае с .equals (Klass var), будет работать? – Jordan Medlock 6 February 2013 в 17:17
  • 2
    Поля по умолчанию видны в подклассах, если подклассы находятся в том же пакете, что и их родительский класс. – Maksim Dmitriev 14 August 2013 в 09:24
  • 3
    В версиях Java и JDK до 1.0.1 вы можете использовать частные и защищенные вместе, чтобы создать еще одну форму защиты, которая ограничивала бы доступ к методам или переменным исключительно подклассам данного класса. – Vitalii Fedorenko 22 August 2013 в 02:37
  • 4
    Это много голосов за ответ, который не отвечает на вопрос, который был , когда мы должны использовать каждую видимость (не то, что эффекты). – Bohemian♦ 29 January 2014 в 01:37
  • 5
    @Bohemian - ответ предполагает, что вы знаете, что когда-нибудь вы должны использовать наименее разрешительный спецификатор доступа (или предполагает, что вы читаете полный ответ, следуя ссылке, которая также дает этот совет). – iheanyi 25 August 2014 в 22:29
                | 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         |       ✔       |     ✘     |       ✘       |   ✘    
165
ответ дан Abdull 15 August 2018 в 19:47
поделиться
  • 1
    Стоит вставить слова - «Защищенный модификатор делает объект доступным для других пакетов, тогда как по умолчанию / no-модификатор ограничивает доступ к одному и тому же пакету» – vanguard69 15 August 2016 в 16:53
  • 2
    @ vanguard69, модификатор protected делает помеченную вещь (класс, метод или поле) доступной для какого-либо другого класса в каком-либо другом пакете , только если f говорит, что другой класс является подкласс класса, где объявлена ​​эта protected - отмеченная вещь . – Abdull 15 August 2016 в 18:14
  • 3
    & Quot; nonsubbed & Quot ;? «этот подкласс в другой упаковке»? Да. Я думал, что знаю Яву. – sehe 10 December 2017 в 13:24
  • 4
    @AlexanderFarber вы оптимизировали для конкретной конфигурации браузера? Это мой хром сейчас , и это Firefox – sehe 10 December 2017 в 13:29
  • 5
    Хм, давайте вернем мое изменение, тогда – Alexander Farber 10 December 2017 в 15:26
  • общедоступный - доступен из любого места приложения.
  • по умолчанию - доступен из пакета.
  • protected - доступен из пакета и подклассов в другом пакете. а также
  • private - доступно только из его класса.
8
ответ дан Alex Weitz 15 August 2018 в 19:47
поделиться
  • Видно для пакета. по умолчанию. Модификаторы не нужны.
  • Видно только для класса: private.
  • Видно миру, public.
  • Видно для пакета и всех подклассов; .

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

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

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

  • Типы нечленов (то есть классы, перечисления, интерфейсы и типы аннотаций, не объявленные внутри другого типа) по умолчанию являются закрытыми по пакетам. ( JLS §6.6.1 )
  • Члены класса и конструкторы по умолчанию закрыты по пакетам. ( JLS §6.6.1 )
  • Конструкторы Enum по умолчанию являются закрытыми. (Действительно, enum contructors должны быть закрытыми, и это ошибка, чтобы попытаться сделать их общедоступными или защищенными). Константы Enum являются общедоступными и не допускают спецификатор доступа. Другие члены перечисления по умолчанию закрыты по пакетам. ( JLS §8.9 )
  • Все члены интерфейсов и типы аннотаций по умолчанию являются общедоступными. (Действительно, члены интерфейсов и типы аннотаций должны быть публичными, и это ошибка, чтобы попытаться сделать их частными или защищенными.) ( JLS §9.3 - 9.5 )
8
ответ дан Boann 15 August 2018 в 19:47
поделиться
  • 1
    И затем, чтобы смутить новичков, новый блестящий модификатор default был добавлен в методы интерфейса в Java 8 :) – Tomas 29 October 2015 в 11:41

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

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

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

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

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

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

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

0
ответ дан Christophe Roussy 15 August 2018 в 19:47
поделиться

Частный

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

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

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

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

Примечание

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

Защищено

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

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

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

Примечание

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

Public

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

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

247
ответ дан Community 15 August 2018 в 19:47
поделиться
  • 1
    Очень ясно. Умный график. Рад видеть, что модули охвачены. Благодаря! – Basil Bourque 11 August 2018 в 22:55

Самый непонятый модификатор доступа в 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 контекстах: внутри класса, который находится в том же пакете, где 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();
        }
    }
    
  • Следующие ситуации недействительны. В ссылке, тип которой является родительским классом, и вне определен пакет 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
        }
    }
    
32
ответ дан Eng.Fouad 15 August 2018 в 19:47
поделиться
  • 1
    Object#clone() является примером члена protected. – Eng.Fouad 15 November 2013 в 22:08
  • 2
    В чем разница между выполнением super.foo() и первой недействительной ситуацией f.foo()? – cst1992 28 October 2017 в 09:18
  • 3
    @ cst1992 Это сбивает с толку, но см. Спецификацию языка Java 6.6.2: «Защищенный член или конструктор объекта может быть доступен извне пакета, в котором он объявляется только кодом, ответственным за реализацию этого объекта». С super.foo () ссылка "super" «непосредственно отвечает за реализацию». но ссылка "f" не является. Зачем? Потому что вы можете быть на 100% уверены, что «супер» имеет тип Father, но не для "f"; во время выполнения это может быть какой-то другой подтип Отца. См. docs.oracle.com/javase/specs/jls/se9/html/… – skomisa 30 January 2018 в 18:55
  • 4
    Это полезно для чтения ответа от человека, который понимает protected. К сожалению, все остальные ответы на этой странице, которые определяют protected, немного ошибочны. – Dawood ibn Kareem 11 July 2018 в 06:20

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

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

  • Когда вы приводите его в университетский городок, первое, что вы и ваш друг видите, это эта статуя. Это означает, что любой, кто ходит в кампусе, может смотреть на статую без разрешения университета. Это делает статую PUBLIC.
  • Затем вы хотите забрать своего друга в общежитие, но для этого вам необходимо зарегистрировать его в качестве посетителя. Это означает, что он получает пропуск доступа (который такой же, как ваш), чтобы попасть в различные здания на территории кампуса. Это сделало бы его карточку доступа ЗАЩИЩЕНА.
  • Ваш друг хочет войти в университетский городок WiFi, но у него нет никаких учетных данных. Единственный способ, по которому он может выйти в интернет, - это поделиться своим логином с ним. (Помните, что каждый студент, который идет в университет, также обладает этими учетными данными). Это сделало бы ваши учетные данные как NO MODIFIER.
  • Наконец, ваш друг хочет прочитать ваш отчет о проделанной работе за семестр, который размещен на веб-сайте. Однако каждый студент имеет свой личный логин для доступа к этому разделу веб-сайта кампуса. Это сделало бы эти полномочия как PRIVATE.

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

5
ответ дан Greedy Coder 15 August 2018 в 19:47
поделиться

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

15
ответ дан Joe Phillips 15 August 2018 в 19:47
поделиться

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

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

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

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

131
ответ дан kvantour 15 August 2018 в 19:47
поделиться
  • 1
    @RuchirBaronia, "world" = весь код в приложении, независимо от того, где он находится. – Andrejs 26 February 2016 в 20:12

Как правило:

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

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

g9]

  • (D) direct (вызов из метода внутри одного класса).
  • (R) 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   |
+—————————————————+————————————+———————————+
63
ответ дан nxhoaf 15 August 2018 в 19:47
поделиться

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

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

15
ответ дан Peter Mortensen 15 August 2018 в 19:47
поделиться
  • 1
    Просто добавьте это & ​​quot; Как только ребенок получит доступ к защищенному члену родительского класса, он станет закрытым (или, вернее, я бы сказал, что специальный частный член, который может быть унаследован подклассами подкласса) члена подкласса. & Quot; – Anand 27 October 2012 в 19:55

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

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

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

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

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

4
ответ дан Pritam Banerjee 15 August 2018 в 19:47
поделиться

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

  • public: доступный извне.
  • protected: доступно классами одного и того же пакета и подклассами, находящимися в любом пакете.
  • по умолчанию (не указан модификатор): доступен классами одного и того же пакета.
  • private: доступно только в одном классе.
43
ответ дан Ravi 15 August 2018 в 19:47
поделиться

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

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

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

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

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

5
ответ дан richa_v 15 August 2018 в 19:47
поделиться
  • 1
    Default не является модификатором доступа, а два других - с ошибкой. – user207421 24 September 2016 в 03:13

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

Private

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

Пакет Private

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

Защищенный

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

Public

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

Опубликован

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

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

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

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

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

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

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

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

358
ответ дан Schwern 15 August 2018 в 19:47
поделиться
  • 1
    друзья - & gt; «Чем меньше вы знаете об этом, тем лучше». --- & GT; Это дает избирательную видимость, которая по-прежнему превосходит конфиденциальность пакета. В C ++ у него есть свои возможности, потому что не все функции могут быть функциями-членами, а друзья лучше, чем публичные. Разумеется, существует опасность злоупотребления злыми умами. – Sebastian Mach 7 June 2011 в 11:13
  • 2
    Следует также отметить, что "защищенный" в C ++ имеет другое значение - защищенный метод является фактически приватным, но все равно может быть вызван из класса наследования. (В отличие от Java, где он может быть вызван любым классом внутри одного и того же пакета.) – Rhys van der Waerden 2 October 2011 в 13:34
  • 3
    @RhysvanderWaerden C # такой же, как C ++ в этом аспекте. Мне показалось довольно странным, что Java не позволяет объявлять член, доступный для подкласса, но не весь пакет. Это перевернуто для меня - пакет более широкий, чем детский класс! – Konrad Morawski 15 October 2013 в 18:36
  • 4
    @KonradMorawski IMHO пакет меньше, чем подкласс. Если вы еще не объявили окончательный выпуск своего класса, пользователи должны иметь возможность подклассифицировать его, поэтому защита java является частью вашего опубликованного интерфейса. OTOH, пакеты неявно разрабатываются одной организацией: например, com.mycompany.mypackage. Если ваш код объявляет себя в моем пакете, вы неявно объявляете себя частью моей организации, поэтому мы должны общаться. Таким образом, пакет публикует более / менее доступную аудиторию (людей в моей компании), чем подкласс (люди, которые расширяют мой объект), и поэтому считается более низкой видимостью. – Eponymous 22 May 2014 в 21:37
  • 5
    friend хорош для определения особых отношений между классами. Он позволяет во многих случаях обеспечить превосходную инкапсуляцию при правильном использовании. Например, он может использоваться привилегированным заводским классом для ввода внутренних зависимостей в построенный тип. У него плохое имя, потому что люди, которые не заботятся о правильном поддержании хорошо продуманной объектной модели, могут злоупотреблять им, чтобы облегчить их рабочую нагрузку. – Dennis 8 December 2014 в 11:05

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

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

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

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

  • Элемент списка
  • private
  • default (package)
  • protected
  • public

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

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

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

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

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

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

6
ответ дан ישו אוהב אותך 15 August 2018 в 19:47
поделиться
  • 1
    что такое дополнение, и почему это не редактирование существующего сообщения? – sehe 17 November 2016 в 16:39
  • 2
    дополнение - модификаторы доступа. Почему не редактирование? Чтобы сохранить принятый ответ неизменным в историческом плане и дать свой ответ. – ישו אוהב אותך 18 November 2016 в 03:25

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

Доступ по умолчанию (указанный отсутствием ключевого слова) также называется 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].)
  • Вам нужен доступ к конструктору для построения объекта. Таким образом, если все конструкторы являются частными, класс может быть создан только кодом, живущим внутри класса (обычно статические фабричные методы или инициализаторы статической переменной). Аналогично для конструкторов private-private или protected. Только наличие частных конструкторов также означает, что класс не может быть подклассифицирован извне, поскольку 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

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

247
ответ дан Community 15 August 2018 в 19:47
поделиться

Эта страница хорошо пишет о защищенном & amp; модификатор доступа по умолчанию

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

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

15
ответ дан Peter Mortensen 15 August 2018 в 19:47
поделиться
  • 1
    Просто добавьте это & ​​quot; Как только ребенок получит доступ к защищенному члену родительского класса, он станет закрытым (или, вернее, я бы сказал, что специальный частный член, который может быть унаследован подклассами подкласса) члена подкласса. & Quot; – Anand 27 October 2012 в 19:55
255
ответ дан Community 5 September 2018 в 19:02
поделиться
15
ответ дан Peter Mortensen 5 September 2018 в 19:02
поделиться
15
ответ дан Peter Mortensen 29 October 2018 в 03:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: