В Java существуют четкие правила о том, когда использовать каждый из модификаторов доступа, а именно по умолчанию (частный пакет), public
, protected
и private
, делая class
и interface
и обрабатывая с наследованием?
В чем разница между общедоступными, защищенными, пакетными и частными в Java?
Ответ 1
Официальный учебник может быть вам полезен.
______________________________________________________________ | │ Class │ Package │ Subclass │ Subclass │ World | | │ │ │(same pkg)│(diff pkg)│ | |───────────┼───────┼─────────┼──────────┼──────────┼────────| |public │ + │ + │ + │ + │ + | |───────────┼───────┼─────────┼──────────┼──────────┼────────| |protected │ + │ + │ + │ + │ | |───────────┼───────┼─────────┼──────────┼──────────┼────────| |no modifier│ + │ + │ + │ │ | |───────────┼───────┼─────────┼──────────┼──────────┼────────| |private │ + │ │ │ │ | |___________|_______|_________|__________|__________|________| + : accessible blank : not accessible
Ответ 2
(Caveat: Я не программист на Java, я программист Perl. Perl не имеет формальных защит, возможно, поэтому я так хорошо понимаю проблему:))
Частный
Как вы думаете, это может увидеть только класс, в котором он объявлен.
Частный пакет
Может отображаться и использоваться только пакетом, в котором он был объявлен. Это значение по умолчанию в Java (которое некоторые считают ошибкой).
Protected
Пакет Private + можно увидеть подклассами или членом пакета.
Public
Каждый может видеть это.
Published
Видимый вне кода, который я контролирую. (Хотя это не синтаксис Java, это важно для этого обсуждения).
С++ определяет дополнительный уровень, называемый "friend", и чем меньше вы знаете, тем лучше.
Когда вы должны использовать что? Вся идея заключается в инкапсуляции, чтобы скрыть информацию. Насколько это возможно, вы хотите скрыть детали того, как что-то делается от ваших пользователей. Зачем? Потому что тогда вы можете изменить их позже и не сломать никому. Это позволяет оптимизировать, реорганизовать, перепроектировать и исправить ошибки, не опасаясь, что кто-то использует этот код, который вы только что пересмотрели.
Итак, эмпирическое правило состоит в том, чтобы сделать вещи такими же видимыми, какими они должны быть. Начните с частных и только добавьте больше видимости по мере необходимости. Публикуйте только то, что абсолютно необходимо для пользователя, чтобы знать, каждая деталь, которую вы делаете публичными, создает вашу способность перепроектировать систему.
Если вы хотите, чтобы пользователи могли настраивать поведение, а не открывать внутренности, чтобы они могли их переопределить, часто лучше перетащить эти кишки в объект и сделать этот интерфейс общедоступным. Таким образом, они могут просто подключить новый объект. Например, если вы пишете проигрыватель компакт-дисков и хотите, чтобы бит "идти найти информацию об этом компакт-диске" настраивался, а не публиковать эти методы, вы включили бы все эти функции в свой собственный объект и сделали бы свой объект getter/setter общедоступным, Таким образом, скупость о том, чтобы разоблачить ваши кишки, поощряет хороший состав и разделение проблем.
Лично я придерживаюсь только "private" и "public". У многих языков OO есть это. "Защищенный" может пригодиться, но это действительно чит. Как только интерфейс более чем частный, это вне вашего контроля, и вам нужно искать в коде других людей, чтобы найти его.
Здесь возникает идея "опубликования". Изменение интерфейса (рефакторинг) требует, чтобы вы нашли весь код, который его использует, и измените его. Если интерфейс частный, то проблем нет. Если он защищен, вам нужно найти все ваши подклассы. Если это публично, вам нужно найти весь код, который использует ваш код. Иногда это возможно, например, если вы работаете с корпоративным кодом, который используется только для внутреннего использования, не имеет значения, открыт ли интерфейс. Вы можете извлечь весь код из корпоративного репозитория. Но если интерфейс "опубликован", если есть код, использующий его вне вашего контроля, тогда вы будете закрыты. Вы должны поддерживать этот интерфейс или код нарушения риска. Даже защищенные интерфейсы могут считаться опубликованными (поэтому я не беспокоюсь о защите).
Многие языки находят иерархическую природу публичной/защищенной/частной слишком ограничивающей и не соответствующей действительности. С этой целью существует концепция класса , но это другое шоу.
Ответ 3
Здесь лучшая версия таблицы. (Будущее с колонкой для модулей.)
Пояснения
-
Закрытый член (
i
) доступен только в том же классе, что и объявленный. -
Член без модификатора доступа (
j
) доступен только внутри классов в одном пакете. -
Защищенный член (
k
) доступен во всех классах в одном пакете и в подклассах в других пакетах. -
Открытый член (
l
) доступен для всех классов (если только он не находится в модуле, который не экспортирует пакет, в котором он объявлен).
Какой модификатор выбрать?
Модификаторы доступа - это инструмент, помогающий предотвратить случайное нарушение инкапсуляции (*). Спросите себя, хотите ли вы, чтобы член был чем-то внутренним для класса, пакета, иерархии классов или не внутренним, и выберите соответствующий уровень доступа.
Примеры:
- Поле
long internalCounter
вероятно, должно быть закрытым, поскольку оно изменчиво и является деталью реализации. - Класс, который должен создаваться только в фабричном классе (в том же пакете), должен иметь конструктор с ограниченным пакетом, так как не должно быть возможности вызывать его напрямую из пакета.
- Внутренний метод
void beforeRender()
вызываемый непосредственно перед рендерингом и используемый как ловушка в подклассах, должен быть защищен. -
void saveGame(File dst)
который вызывается из кода GUI, должен быть открытым.
Ответ 4
| 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 | ✔ | ✘ | ✘ | ✘
____________________________________________________________________
Ответ 5
Простое правило. Начните с объявления всех частных. И затем прогресс в отношении общественности по мере возникновения потребностей, и дизайн ее оправдывает.
Когда выставлять участников, спросите себя, подвергаете ли вы выбор выбора или выбор абстракции. Первое - это то, чего вы хотите избежать, поскольку оно будет вводить слишком много зависимостей от фактического представления, а не от его наблюдаемого поведения.
Как правило, я стараюсь избегать переопределения реализации метода путем подкласса; это слишком легко заглушить логику. Объявите абстрактные защищенные методы, если вы намерены переопределить его.
Кроме того, используйте аннотацию @Override, когда вы переопределяете, чтобы вещи не ломались, когда вы реорганизуете.
Ответ 6
Это на самом деле немного сложнее, чем простые сетки. В сетке указано, разрешен ли доступ, но что именно представляет собой доступ? Кроме того, уровни доступа взаимодействуют с вложенными классами и наследованием сложными способами.
Доступ по умолчанию (указанный отсутствием ключевого слова) также называется 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
Некоторые связанные вопросы:
Ответ 7
Как правило большого пальца:
-
private
: область видимости -
default
(илиpackage-private
): область действия пакета. -
protected
:package scope + child
(как пакет, но мы можем подкласс его из разных пакетов). Защищенный модификатор всегда сохраняет отношения "родитель-потомок". -
public
: везде.
В результате, если мы разделим право доступа на три права:
- (D) irect (вызывается из метода внутри того же класса или через синтаксис this).
- (R) eference (вызывать метод, используя ссылку на класс или через синтаксис "точка").
- (I) наследование (через подклассы).
тогда у нас есть эта простая таблица:
+—-———————————————+————————————+———————————+
| | Same | Different |
| | Package | Packages |
+—————————————————+————————————+———————————+
| private | D | |
+—————————————————+————————————+———————————+
| package-private | | |
| (no modifier) | D R I | |
+—————————————————+————————————+———————————+
| protected | D R I | I |
+—————————————————+————————————+———————————+
| public | D R I | R I |
+—————————————————+————————————+———————————+
Ответ 8
В очень короткие
-
public
: доступен везде. -
protected
: доступ к классам одного и того же пакета и подклассам, находящимся в любом пакете. - default (не указан модификатор): доступен классами одного и того же пакета.
-
private
: доступен только в одном классе.
Ответ 9
Самый непонятый модификатор доступа в 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 } }
-
Ответ 10
Частный
- Методы, переменные и конструкторы
Методы, переменные и конструкторы, объявленные как 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
Ответ 11
Разницу можно найти в уже упомянутых ссылках, но тот, который используется, обычно сводится к "Принципу наименьшего знания". Только разрешите минимальную видимость, которая необходима.
Ответ 12
Частный: ограниченный доступ только к классу
По умолчанию (без модификатора): ограниченный доступ к классу и пакету
Защищенный: ограниченный доступ к классу, пакету и подклассам (как внутри, так и снаружи)
Публичный: доступ к классу, пакету (все) и подклассам... Короче говоря, везде.
Ответ 13
Модификаторы доступа предназначены для ограничения доступа на нескольких уровнях.
Публикация:. Это в основном так же просто, как вы можете получить доступ из любого класса, будь то в одном пакете или нет.
Чтобы получить доступ, если вы находитесь в одном пакете, вы можете получить доступ напрямую, но если вы находитесь в другом пакете, вы можете создать объект класса.
По умолчанию: Он доступен в одном пакете из любого класса пакета.
Для доступа вы можете создать объект класса. Но вы не можете получить доступ к этой переменной за пределами пакета.
Защищено: вы можете получить доступ к переменным в том же пакете, а также подклассе в любом другом пакете. поэтому в основном это default + Inherited.
Для доступа к защищенному полю, определенному в базовом классе, вы можете создать объект дочернего класса.
Частный: он может иметь доступ в том же классе.
В нестатических методах вы можете получить доступ напрямую из-за ссылки this (также в конструкторах), но для доступа к статическим методам вам необходимо создать объект класса.
Ответ 14
Модификаторы доступа в 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();
}
}
Вывод: Привет
Ответ 15
Видимый для пакета. По умолчанию. Модификаторы не нужны.
Только для класса (частный).
Видно миру (общедоступный).
Видимый для пакета и всех подклассов (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(){
}
}
Ответ 16
-
общедоступный - доступен из любого места приложения.
-
default - доступен из пакета.
-
защищенный - доступен из пакета и подклассов в другом пакете. а также
-
закрытый - доступен только из его класса.
Ответ 17
Я просто хочу обратиться к деталям, которые чрезвычайно часто ошибаются, в том числе большинством ответов на этой странице. "Доступ по умолчанию" (если нет модификатора доступа) не всегда совпадает с пакетом-частным. Это зависит от того, что это такое.
-
Типы нечленов (то есть классы, перечисления, интерфейсы и типы аннотаций, не объявленные внутри другого типа) по умолчанию являются закрытыми по пакетам. (JLS §6.6.1)
-
Члены класса и конструкторы по умолчанию закрыты по пакетам. (JLS §6.6.1)
-
Конструкторы Enum по умолчанию закрыты по умолчанию. (В самом деле, enum contructors должны быть частными, и это ошибка, чтобы попытаться сделать их публичными или защищенными). Константы Enum являются общедоступными и не допускают спецификатор доступа. Другие члены перечисления по умолчанию закрыты по пакетам. (JLS §8.9)
-
Все члены интерфейсов и типы аннотаций общедоступны по умолчанию. (Действительно, члены интерфейсов и типы аннотаций должны быть общедоступными, и это ошибка, чтобы попытаться сделать их частными или защищенными.) (JLS §9.3 - 9.5)
Ответ 18
Эта страница хорошо описывает защищенный и модифицированный по умолчанию модификатор доступа
.... Protected: Защищенный модификатор доступа немного сложнее, и вы можете сказать, что это надмножество модификатора доступа по умолчанию. Защищенные члены такие же, как и члены по умолчанию, в отношении доступа в одном пакете. Разница в том, что защищенные члены также доступны для подклассов класса, в котором объявлен член, который находится вне пакета, в котором присутствует родительский класс.
Но эти защищенные члены "доступны вне пакета только через наследование". т.е. вы можете получить доступ к защищенному элементу класса в своем подклассе, присутствующем в каком-либо другом пакете, как если бы этот член присутствовал в самом подклассе. Но этот защищенный член не будет доступен в подклассе вне пакета, используя ссылку на родительские классы. ....
Ответ 19
Ответ Дэвида дает смысл каждого модификатора доступа. Что касается того, когда использовать каждый, я предлагаю публиковать все классы и методы каждого класса, предназначенные для внешнего использования (его API), и все остальное частное.
С течением времени у вас возникнет смысл, когда нужно сделать некоторые классы private-private и когда объявлять определенные методы, защищенные для использования в подклассах.
Ответ 20
- Видимый для пакета. по умолчанию. Модификаторы не нужны.
- Только для класса private.
- Видно миру; общедоступный.
- Видимый для пакета и всех подклассов защищенный.
Итак, поговорим о контроле доступа и наследовании Следующие правила для унаследованных методов:
- Объявленные методы
public
в суперклассе также должны быть общедоступными во всех подклассы. - Объявленные методы
protected
в суперклассе должны бытьprotected
илиpublic
в подклассах; они не могут быть частными. - Способы, объявленные без контроля доступа (без использования модификатора), могут быть объявлено более приватным в подклассах.
- Объявленные методы
private
не наследуются вообще, поэтому нет правило для них.
Ответ 21
Примечание. Это только дополнение для принятого ответа.
Это связано с 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, уровни доступа определяют, какие члены этих классов классы могут использовать. Во-вторых, когда вы пишете класс, вам нужно решить какой уровень доступа каждый член переменной и каждый метод в вашем классе должен иметь.
Ответ 22
Public Protected Default и private - модификаторы доступа.
Они предназначены для инкапсуляции или скрытия и отображения содержимого класса.
- Класс может быть общедоступным или по умолчанию
- Члены класса могут быть общедоступными, защищенными, стандартными или частными.
Частный недоступен вне класса Значение по умолчанию доступно только в пакете. Защищен в пакете, а также в любом классе, который его расширяет. Публикация открыта для всех.
Обычно переменные-члены определяются частными, но методы-члены являются общедоступными.
Ответ 23
Часто я осознавал, что запоминание основных понятий любого языка может быть сделано путем создания реальных аналогов. Вот моя аналогия для понимания модификаторов доступа в Java:
Предположим, что вы студент в университете, и у вас есть друг, который приезжает к вам в выходные. Предположим, существует большая статуя основателя университета в центре кампуса.
-
Когда вы приведете его в университетский городок, первое, что вы и ваш друг видите, это эта статуя. Это означает, что любой, кто ходит в кампусе, может смотреть на статую без разрешения университета. Это делает статую PUBLIC.
-
Затем вы хотите забрать своего друга в общежитие, но для этого вам необходимо зарегистрировать его в качестве посетителя. Это означает, что он получает пропуск доступа (который такой же, как ваш), чтобы попасть в различные здания на территории кампуса. Это сделало бы его карточку доступа ЗАЩИЩЕНА.
-
Ваш друг хочет войти в университетский городок WiFi, но у него нет никаких учетных данных. Единственный способ, по которому он может выйти в интернет, - это поделиться своим логином с ним. (Помните, что каждый студент, который идет в университет, также обладает этими учетными данными). Это сделало бы ваши учетные данные как НЕТ МОДИФИКАЦИЯ.
-
Наконец, ваш друг хочет прочитать ваш отчет о проделанной работе за семестр, который размещен на веб-сайте. Однако каждый студент имеет свой личный логин для доступа к этому разделу веб-сайта кампуса. Это сделало бы эти учетные данные как ЧАСТНЫМ.
Надеюсь, это поможет!
Ответ 24
Когда вы думаете о модификаторах доступа, просто подумайте об этом таким образом (применительно к переменным и методам):
public
→ доступно из любого места
private
→ доступен только в том же классе, где он объявлен
Теперь возникает путаница, когда дело доходит до default
и protected
default
→ Нет ключевого слова модификатора доступа. Это означает, что он доступен строго в пакете класса. Нигде за пределами этого пакета он может быть доступен.
protected
→ Чуть менее строгий, чем default
, и помимо тех же классов пакетов он может быть доступен подклассам вне объявленного пакета.
Ответ 25
Модификаторы доступа
Мне нравится статья Jenkov
Следующая таблица суммирует, к каким Java-конструкциям может быть применен каждый модификатор доступа к Java:
частный
Если метод или переменная помечены как частные (им назначен модификатор личного доступа), то только код внутри того же класса может получить доступ к переменной или вызвать метод. Код внутри подклассов не может получить доступ к переменной или методу, равно как и код из любого внешнего класса.
Классы не могут быть помечены модификатором частного доступа. Пометка класса с помощью модификатора частного доступа будет означать, что никакой другой класс не сможет получить к нему доступ, а это означает, что вы вообще не сможете использовать этот класс. Поэтому модификатор закрытого доступа недопустим для классов.
дефолт
Модификатор доступа Java по умолчанию объявляется без записи модификатора доступа вообще. Модификатор доступа по умолчанию означает, что код внутри самого класса, а также код внутри классов в том же пакете, что и этот класс, могут обращаться к классу, полю, конструктору или методу, которому назначен модификатор доступа по умолчанию. Поэтому модификатор доступа по умолчанию также иногда называют модификатором доступа к пакету.
защищенный
Модификатор защищенного доступа обеспечивает тот же доступ, что и модификатор доступа по умолчанию, с тем добавлением, что подклассы могут обращаться к защищенным методам и переменным (полям) членов суперкласса. Это верно, даже если подкласс не находится в том же пакете, что и суперкласс.
общественности
Открытый модификатор доступа Java означает, что весь код может получить доступ к классу, полю, конструктору или методу независимо от того, где находится код доступа. Код доступа может быть в другом классе и в другом пакете.
Ответ 26
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.
Ответ 27
Все дело в инкапсуляции (или, как сказал Джо Филлипс, наименьшее знание).
Начните с самого ограничительного (частного) и посмотрите, не понадобится ли вам менее ограничивающие модификаторы.
Мы все используем модификаторы метода и члена, такие как private, public,... но одна вещь, которую слишком мало разработчиков делают, это использовать пакеты для логического упорядочения кода.
Например: вы можете ввести чувствительные методы защиты в пакет безопасности. Затем поместите открытый класс, который обращается к некоторому коду безопасности, содержащемуся в этом пакете, но сохраняет другие классы классов безопасности частными. Таким образом, другие разработчики смогут использовать общедоступный класс вне этого пакета (если только они не изменят модификатор). Это не функция безопасности, но будет определять использование.
Outside world -> Package (SecurityEntryClass ---> Package private classes)
Другое дело, что классы, которые сильно зависят друг от друга, могут оказаться в одном пакете и в конечном итоге могут быть реорганизованы или объединены, если зависимость слишком сильная.
Если, наоборот, вы устанавливаете все как общедоступные, неясно, к чему следует или не следует обращаться, что может привести к написанию большого количества javadoc (что ничего не может сделать с помощью компилятора...).
Ответ 28
общественного
Если член класса объявлен как public, тогда к нему можно получить доступ из любого места
защищенный
Если член класса объявлен с защищенным ключевым словом, то к нему можно получить доступ из тех же членов класса, вне членов класса в том же пакете и унаследованных членов класса. Если член класса защищен, то к нему нельзя получить доступ извне класса пакета, если только внешний упакованный класс не унаследован, то есть расширяет суперкласс другого пакета. Но защищенный член класса всегда доступен для одних и тех же классов пакетов, это НЕ имеет значения, если один и тот же класс пакета унаследован или НЕ
по умолчанию
В Java по умолчанию НЕ используется ключевое слово модификатора доступа. Если член класса объявлен без ключевого слова модификатора доступа, то в этом случае он считается членом по умолчанию. Член класса по умолчанию всегда доступен тем же членам класса пакета. Но внешний член класса пакета НЕ может получить доступ к членам класса по умолчанию, даже если внешние классы являются подклассами в отличие от защищенных членов
частный
Если член класса объявлен с ключевым словом защищен, то в этом случае он доступен ТОЛЬКО для тех же членов класса
Ответ 29
Следующая блок-схема объясняет, как члены данных базового класса are наследуются, когда производный класс имеет режим доступа закрытый.
Примечание. Объявление членов данных с указателем закрытого доступа называется скрытием данных.
Источник: Спецификаторы доступа - частные, открытые и защищенные
Ответ 30
Мои два цента :)
частные:
класс → класс верхнего уровня не может быть закрытым. внутренние классы могут быть приватными, которые доступны из того же класса.
переменная экземпляра → доступна только в классе. Невозможно получить доступ за пределами класса.
Пакет-частное:
class → класс верхнего уровня может быть закрытым для пакета. Он может быть доступен только из одного пакета. Не из дополнительного пакета, не из внешнего пакета.
переменная экземпляра → доступна из того же пакета. Не из дополнительного пакета, не из внешнего пакета.
защищенный:
class → класс верхнего уровня не может быть защищен.
переменная экземпляра → Доступна только в том же пакете или подпакете. Доступ может быть только вне пакета при расширении класса.
общественности:
класс → доступный из пакета/подпакета/другого пакета
переменная экземпляра → доступная из пакета/подпакета/другого пакета
Дайте мне знать, я напишу несколько примеров :)