В Java существуют четкие правила использования каждого из модификаторов доступа, а именно значения по умолчанию (частный пакет), public
, protected
и private
, при создании class
и interface
и имеете дело с наследованием?
29 ответов
(Предостережение: я не программист на Java, я программист на Perl. Perl не имеет формальной защиты, возможно, поэтому я так хорошо понимаю проблему :))
Частный
Как вы думаете, его видит только класс , в котором он объявлен.
Пакет Частный
Его можно увидеть и использовать только в том пакете , в котором он был объявлен. Это значение по умолчанию в Java (что некоторые считают ошибкой).
Защищено
Пакет Private + можно увидеть подклассам или членам пакета.
Общественного
Это все видят.
Опубликовано
Виден за пределами контролируемого мной кода. (Хотя это и не синтаксис Java, он важен для этого обсуждения).
C ++ определяет дополнительный уровень, называемый «друг», и чем меньше вы об этом знаете, тем лучше.
Когда вы должны использовать что? Вся идея заключается в инкапсуляции для сокрытия информации. Насколько это возможно, вы хотите скрыть детали того, как что-то делается, от ваших пользователей. Почему? Потому что тогда вы сможете изменить их позже и не нарушить чей-либо код. Это позволяет вам оптимизировать, рефакторить, перепроектировать и исправлять ошибки, не беспокоясь о том, что кто-то использует только что переработанный вами код.
Таким образом, эмпирическое правило состоит в том, чтобы делать вещи настолько видимыми, насколько они должны быть. Начните с частного и добавляйте больше видимости только по мере необходимости. Публикуйте только то, что необходимо знать пользователю, каждая деталь, которую вы публикуете, ограничивает вашу способность перепроектировать систему.
Если вы хотите, чтобы пользователи могли настраивать поведение, а не публиковать внутренности, чтобы они могли их переопределить, часто бывает лучше засунуть эти внутренности в объект и сделать этот интерфейс общедоступным. Таким образом, они могут просто подключить новый объект. Например, если вы пишете проигрыватель компакт-дисков и хотите, чтобы бит «найти информацию об этом компакт-диске» был настраиваемым, вместо того, чтобы делать эти методы общедоступными, вы поместили бы всю эту функциональность в его объект и сделали бы общедоступным только ваш метод получения/установки объекта. Таким образом, скупость на обнажение своих внутренностей способствует хорошему сочинению и разделению интересов.
Я придерживаюсь только «частного» и «общественного». Многие языки OO просто имеют это. «Защищено» может быть удобно, но это обман. Как только интерфейс становится более чем приватным, он выходит за пределы вашего контроля, и вам приходится искать применение в чужом коде.
Вот тут-то и появляется идея «опубликованного». Для изменения интерфейса (рефакторинга) необходимо, чтобы вы нашли весь код, который его использует, и изменили его тоже. Если интерфейс частный, нет проблем. Если он защищен, вам нужно найти все свои подклассы. Если он общедоступен, вам нужно найти весь код, который использует ваш код. Иногда это возможно, например, если вы работаете над корпоративным кодом, предназначенным только для внутреннего использования, не имеет значения, является ли интерфейс общедоступным. Вы можете взять весь код из корпоративного репозитория. Но если интерфейс «опубликован», если есть код, использующий его вне вашего контроля, то вы попали в беду. Вы должны поддерживать этот интерфейс, иначе вы рискуете взломать код. Даже защищенные интерфейсы можно считать опубликованными (поэтому я не заморачиваюсь с защищенными).
Многие языки считают иерархическую природу общедоступного / защищенного / частного слишком ограничивающей и не соответствующей действительности. Для этого существует концепция класса признаков, но это уже другое шоу.
friend
хорошо подходит для определения особых отношений между классами. Во многих случаях при правильном использовании он обеспечивает превосходную инкапсуляцию. Например, он может использоваться привилегированным классом фабрики для внедрения внутренних зависимостей в сконструированный тип. У него плохая репутация, потому что люди, которые не заботятся о правильной поддержке хорошо спроектированной объектной модели, могут злоупотреблять ею, чтобы облегчить свою рабочую нагрузку.
Вот лучшая версия таблицы, которая также включает столбец для модулей.
Пояснения
закрытый член (
i
) доступен только в том же классе, в котором он объявлен.Член с без модификатора доступа (
j
) доступен только внутри классов в том же пакете.Защищенный член (
k
) доступен во всех классах того же пакета и в подклассах других пакетов.Член public (
l
) доступен для всех классов (если только он не находится в модуль, который не экспортирует пакет, в котором он объявлен).
Какой модификатор выбрать?
( * )
Примеры:
- Поле
long internalCounter
, вероятно, должно быть закрытым, поскольку оно изменяемое и является деталью реализации. - Класс, который должен быть создан только в фабричном классе (в том же пакете), должен иметь конструктор, ограниченный пакетом, поскольку не должно быть возможности вызвать его напрямую извне пакета.
- Внутренний метод
void beforeRender()
, вызываемый прямо перед рендерингом и используемый как перехватчик в подклассах, должен быть защищен. - Метод
void saveGame(File dst)
, который вызывается из кода графического интерфейса пользователя, должен быть общедоступным.
____________________________________________________________________
| highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
\ xCanBeSeenBy | this | any class | this subclass | any
\__________ | class | in same | in another | class
\ | nonsubbed | package | package |
Modifier of x \ | | | |
————————————————*———————————————+———————————+———————————————+———————
public | ✔ | ✔ | ✔ | ✔
————————————————+———————————————+———————————+———————————————+———————
protected | ✔ | ✔ | ✔ | ✘
————————————————+———————————————+———————————+———————————————+———————
package-private | | | |
(no modifier) | ✔ | ✔ | ✘ | ✘
————————————————+———————————————+———————————+———————————————+———————
private | ✔ | ✘ | ✘ | ✘
____________________________________________________________________
protected
делает отмеченный объект (класс, метод или поле) доступным какому-то другому классу в каком-то другом пакете , только если указанный другой класс является подклассом класса, в котором объявлена эта protected
- отмеченная вещь .
Простое правило. Начните с объявления всего приватным. А затем продвигайтесь к общественности по мере возникновения потребностей и того, что того требует дизайн.
Разоблачая участников, спросите себя, раскрываете ли вы варианты представления или варианты абстракции. Первое - это то, чего вы хотите избежать, так как это приведет к слишком большому количеству зависимостей от фактического представления, а не от его наблюдаемого поведения.
Как правило, я стараюсь избегать переопределения реализаций методов путем создания подклассов; слишком легко запутать логику. Объявите абстрактные защищенные методы, если вы намереваетесь их переопределить.
Кроме того, используйте аннотацию @Override при переопределении, чтобы не допустить поломки при рефакторинге.
На самом деле это немного сложнее, чем показывает простая сетка. Сетка сообщает вам, разрешен ли доступ, но что именно составляет доступ? Кроме того, уровни доступа сложным образом взаимодействуют с вложенными классами и наследованием.
Доступ "по умолчанию" (определяемый отсутствием ключевого слова) также называется package-private < / strong>. Исключение: в интерфейсе отсутствие модификатора означает открытый доступ; модификаторы, отличные от общедоступных, запрещены. Константы перечисления всегда открыты.
Резюме
Разрешен ли доступ к члену с этим спецификатором доступа?
- Член
private
: только если член определен в том же классе, что и вызывающий код. - Член является частным пакетом: только если вызывающий код находится в пакете, непосредственно включающем член.
- Член
protected
: тот же пакет, или если член определен в суперклассе класса, содержащего вызывающий код. - Участник
public
: Да.
Какие спецификаторы доступа применяются к
Локальные переменные и формальные параметры не могут принимать спецификаторы доступа. Поскольку они по своей сути недоступны извне в соответствии с правилами области видимости, они фактически являются частными.
Для классов в верхней области разрешены только public
и package-private. Этот выбор конструкции предположительно вызван тем, что protected
и private
будут избыточными на уровне пакета (нет наследования пакетов).
Все спецификаторы доступа возможны для членов класса (конструкторы, методы и статические функции-члены, вложенные классы).
Связано: Доступность классов Java
Порядок
Спецификаторы доступа могут быть строго упорядочены.
общедоступный> защищенный> частный пакет> частный
Это означает, что public
предоставляет наибольший доступ, private
наименьший. Любая ссылка, возможная на частный член, также действительна для частного члена пакета; любая ссылка на частный член пакета действительна для защищенного члена и т. д. (Предоставление доступа к защищенным членам другим классам в том же пакете считалось ошибкой.)
Примечания
- Методам класса разрешен доступ к закрытым членам других объектов того же класса. Точнее, метод класса C может обращаться к закрытым членам C в объектах любого подкласса C. Java не поддерживает ограничение доступа по экземплярам, только по классам. (Сравните со Scala, который поддерживает его с помощью
private[this]
.) - Для создания объекта вам нужен доступ к конструктору. Таким образом, если все конструкторы являются частными, класс может быть создан только кодом, живущим внутри класса (обычно статические фабричные методы или инициализаторы статических переменных). Аналогично для конструкторов с закрытым пакетом или защищенными конструкторами.
- Наличие только частных конструкторов также означает, что класс не может быть подклассом извне, поскольку Java требует, чтобы конструкторы подкласса неявно или явно вызывали конструктор суперкласса. (Однако он может содержать вложенный класс, являющийся его подклассом.)
Внутренние классы
Вы также должны учитывать вложенные области, например внутренние классы. Примером сложности является то, что внутренние классы имеют члены, которые сами могут принимать модификаторы доступа. Таким образом, у вас может быть частный внутренний класс с открытым членом; можно получить доступ к члену? (См. Ниже.) Общее правило - смотреть на область видимости и думать рекурсивно, чтобы увидеть, можете ли вы получить доступ к каждому уровню.
Однако это довольно сложно, и для получения полной информации см. обратитесь к Спецификации языка Java . (Да, в прошлом были ошибки компилятора.)
Чтобы понять, как они взаимодействуют, рассмотрим этот пример. Возможна «утечка» частных внутренних классов; обычно это предупреждение:
class Test {
public static void main(final String ... args) {
System.out.println(Example.leakPrivateClass()); // OK
Example.leakPrivateClass().secretMethod(); // error
}
}
class Example {
private static class NestedClass {
public void secretMethod() {
System.out.println("Hello");
}
}
public static NestedClass leakPrivateClass() {
return new NestedClass();
}
}
Выход компилятора:
Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
Example.leakPrivateClass().secretMethod(); // error
^
1 error
Некоторые связанные вопросы:
Как правило большого пальца:
private
: объем класса.default
(илиpackage-private
): объем пакета.protected
:package scope + child
(как package, но мы можем создать подклассы из разных пакетов). Модификатор protected всегда сохраняет отношения «родитель-потомок».public
: везде.
В результате, если мы разделим право доступа на три права:
- (D) irect (вызов из метода внутри того же класса или с помощью синтаксиса this).
- (R) ссылка (вызов метода с использованием ссылки на класс или синтаксиса с точкой).
- (I) наследование (через создание подклассов).
Тогда у нас есть эта простая таблица:
+—-———————————————+————————————+———————————+
| | Same | Different |
| | Package | Packages |
+—————————————————+————————————+———————————+
| private | D | |
+—————————————————+————————————+———————————+
| package-private | | |
| (no modifier) | D R I | |
+—————————————————+————————————+———————————+
| protected | D R I | I |
+—————————————————+————————————+———————————+
| public | D R I | R I |
+—————————————————+————————————+———————————+
Очень коротко
public
: доступно отовсюду.protected
: доступен классам одного и того же пакета и подклассам, находящимся в любом пакете.- по умолчанию (модификатор не указан): доступен классам того же пакета.
private
: доступен только в рамках того же класса.
Наиболее неправильно понимаемый модификатор доступа в Java - это protected
. Мы знаем, что он похож на модификатор по умолчанию с одним исключением, в котором его могут видеть подклассы. Но как? Вот пример, который, надеюсь, проясняет путаницу:
Предположим, что у нас есть 2 класса;
Father
иSon
, каждый в своем собственном пакете:package fatherpackage; public class Father { } ------------------------------------------- package sonpackage; public class Son extends Father { }
Давайте добавим защищенный метод
foo()
кFather
.package fatherpackage; public class Father { protected void foo(){} }
Метод
foo()
можно вызывать в 4-х контекстах:Внутри класса, расположенного в том же пакете, где определен
foo()
(fatherpackage
):пакет открытый класс SomeClass { public void someMethod(Father f, Son s) { f.foo(); s.foo(); } } код>пре>ли>
Внутри подкласса в текущем экземпляре через
this
илиsuper
:пакет sonpackage; публичный класс сын расширяет отца { public void sonMethod() { это.foo(); супер.foo(); } } код>пре>ли>
Для ссылки, тип которой относится к тому же классу:
пакет Отец публичного класса { public void FatherMethod(Father f) { f.foo(); // действителен, даже если foo() является приватным } } ------------------------------------------- пакетный пакет; публичный класс сын расширяет отца { public void sonMethod(Son s) { s.foo(); } } код>пре>ли>
Для ссылки, тип которой является родительским классом и находится внутри пакета, в котором определено
foo()
(fatherpackage
) [Это может быть включено в контекст нет. 1]:пакет публичный класс сын расширяет отца { public void sonMethod(Father f) { f.foo(); } } код>пре>ли>
Следующие ситуации недопустимы.
Для ссылки, тип которой является родительским классом и находится вне пакета, в котором определен
foo()
(fatherpackage
):пакет sonpackage; публичный класс сын расширяет отца { public void sonMethod(Father f) { f.foo(); // ошибка компиляции } } код>пре>ли>
Не-подкласс внутри пакета подкласса (подкласс наследует защищенные элементы от своего родителя и делает их закрытыми для не-подклассов):
пакет sonpackage; открытый класс SomeClass { public void someMethod(Son s) выдает исключение { s.foo(); // ошибка компиляции } } код>пре>ли>
Object#clone()
- это пример члена protected
.
super.foo()
и первой недопустимой ситуацией f.foo()
?
protected
. К сожалению, все остальные ответы на этой странице, которые определяют protected
, немного ошибаются.
Разницу можно найти в уже предоставленных ссылках, но какая из них обычно сводится к «Принципу наименьшего знания». Обеспечьте минимальную видимость, которая необходима.
Частный : ограниченный доступ только к классу.
По умолчанию (без модификатора) : ограниченный доступ к классу и пакету.
Защищено : ограниченный доступ к классу, пакету и подклассам (как внутри, так и вне пакета).
Общедоступный : доступен для класса, пакета (всех) и подклассов ... Короче говоря, везде.
Модификаторы доступа предназначены для ограничения доступа на нескольких уровнях.
Общедоступный: это в основном так же просто, как вы можете получить доступ из любого класса, независимо от того, находится он в одном пакете или нет.
Чтобы получить доступ, если вы находитесь в одном пакете, вы можете получить доступ напрямую, но если вы находитесь в другом пакете, вы можете создать объект класса.
По умолчанию: он доступен в том же пакете из любого класса пакета.
Для доступа вы можете создать объект класса. Но вы не можете получить доступ к этой переменной вне пакета.
Защищено: вы можете получить доступ к переменным в том же пакете, а также к подклассу в любом другом пакете. так что в основном это поведение по умолчанию + Унаследовано .
Чтобы получить доступ к защищенному полю, определенному в базовом классе, вы можете создать объект дочернего класса.
Личное: это может быть доступ в том же классе.
В нестатических методах вы можете получить доступ напрямую из-за ссылки this (также в конструкторах), но для доступа в статических методах вам необходимо создать объект класса.
Модификаторы доступа в Java.
Модификаторы доступа Java используются для обеспечения контроля доступа в Java.
1. По умолчанию:
Доступно только для классов в одном пакете.
Например,
// Saved in file A.java
package pack;
class A{
void msg(){System.out.println("Hello");}
}
// Saved in file B.java
package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A(); // Compile Time Error
obj.msg(); // Compile Time Error
}
}
Этот доступ более ограничен, чем публичный и защищенный, но менее ограничен, чем частный.
2. Общедоступно
Доступен откуда угодно. (Глобальный доступ)
Например,
// Saved in file A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
// Saved in file B.java
package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A();
obj.msg();
}
}
Выход: Здравствуйте
3. Частный
Доступно только внутри одного класса.
Если вы попытаетесь получить доступ к закрытым членам одного класса, другой вызовет ошибку компиляции. Например,
class A{
private int data = 40;
private void msg(){System.out.println("Hello java");}
}
public class Simple{
public static void main(String args[]){
A obj = new A();
System.out.println(obj.data); // Compile Time Error
obj.msg(); // Compile Time Error
}
}
4. Защищено
Доступен только классам в одном пакете и подклассам
Например,
// Saved in file A.java
package pack;
public class A{
protected void msg(){System.out.println("Hello");}
}
// Saved in file B.java
package mypack;
import pack.*;
class B extends A{
public static void main(String args[]){
B obj = new B();
obj.msg();
}
}
Вывод: Привет
Видно на упаковке. По умолчанию. Никаких модификаторов не требуется.
Видно только классу ( закрытый ).
Видно всему миру ( общедоступно ).
Виден пакету и всем подклассам ( защищен ).
Переменные и методы можно объявлять без каких-либо вызываемых модификаторов. Примеры по умолчанию:
String name = "john";
public int age(){
return age;
}
Модификатор приватного доступа - приватный:
Доступ к методам, переменным и конструкторам, которые объявлены частными, можно получить только внутри самого объявленного класса. Модификатор частного доступа - это самый ограничительный уровень доступа. Класс и интерфейсы не могут быть частными.
Переменные, которые объявлены частными, могут быть доступны вне класса, если в классе присутствуют общедоступные методы получения.
Использование модификатора private - это основной способ инкапсуляции объекта и скрытия данных от внешнего мира.
Примеры:
Public class Details{
private String name;
public void setName(String n){
this.name = n;
}
public String getName(){
return this.name;
}
}
Модификатор публичного доступа - публичный:
К классу, методу, конструктору, интерфейсу и т. Д., Объявленным как общедоступный, можно получить доступ из любого другого класса. Следовательно, к полям, методам и блокам, объявленным внутри общедоступного класса, можно получить доступ из любого класса, принадлежащего юниверсу Java.
Однако, если публичный класс, к которому мы пытаемся получить доступ, находится в другом пакете, то публичный класс все равно необходимо импортировать.
Из-за наследования классов все общедоступные методы и переменные класса наследуются его подклассами.
Примере:
public void cal(){
}
Модификатор защищенного доступа - protected:
Переменные, методы и конструкторы, которые объявлены защищенными в суперклассе, могут быть доступны только подклассам в другом пакете или любому классу в пакете класса защищенных членов.
Модификатор защищенного доступа нельзя применять к классу и интерфейсам. Методы и поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.
Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, предотвращая попытки несвязанного класса использовать их.
class Van{
protected boolean speed(){
}
}
class Car{
boolean speed(){
}
}
общедоступный - доступен из любой точки приложения.
по умолчанию - доступно из пакета.
protected - доступен из пакета и подклассов в другом пакете. также
частный - доступен только из своего класса.
Эта страница хорошо описывает модификатор доступа по умолчанию и защищенный
.... Защищено: Модификатор защищенного доступа немного сложен и, можно сказать, является надмножеством модификатора доступа по умолчанию. Защищенные члены такие же, как члены по умолчанию, что касается доступа в том же пакете. Разница в том, что защищенные члены также доступны для подклассов класса, в котором объявлен член, которые находятся за пределами пакета, в котором присутствует родительский класс.
Но эти защищенные члены «доступны вне пакета только через наследование». то есть вы можете получить доступ к защищенному члену класса в его подклассе, присутствующем в каком-то другом пакете, напрямую, как если бы этот член присутствует в самом подклассе. Но этот защищенный член не будет доступен в подклассе вне пакета с помощью ссылки на родительский класс. ....
Ответ Дэвида объясняет значение каждого модификатора доступа. Что касается того, когда использовать каждый из них, я бы предложил сделать общедоступными все классы и методы каждого класса, которые предназначены для внешнего использования (его API), а все остальное - частным.
Со временем вы научитесь понимать, когда делать некоторые классы закрытыми для пакетов, а когда объявлять определенные методы защищенными для использования в подклассах.
Это изображение поможет вам легко понять основные различия между модификаторами доступа public, private, protected и default. Модификатор по умолчанию применяется автоматически, если вы не объявляете в своем коде модификаторы доступа ant.
no modifier
== package private
| package protected
Public Protected Default и private являются модификаторами доступа.
Они предназначены для инкапсуляции или скрытия и отображения содержимого класса.
- Класс может быть общедоступным или по умолчанию
- Члены класса могут быть общедоступными, защищенными, по умолчанию или частными.
Private недоступен за пределами класса. Default доступен только в пакете. Защищено как в пакете, так и в любом расширяющем его классе. Публика открыта для всех.
Обычно переменные-члены определены как частные, но методы-члены являются общедоступными.
Default
не является модификатором доступа, а два других написаны с ошибками.
Примечание. Это просто дополнение к принятому ответу.
Это связано с модификаторами доступа Java.
Модификатор доступа Java указывает, какие классы могут получить доступ к данному классу и его полям, конструкторам и методам. Модификаторы доступа можно указать отдельно для класса, его конструкторов, полей и методов. Модификаторы доступа Java также иногда упоминаются в повседневной речи как спецификаторы доступа Java, но правильное название - модификаторы доступа Java. Классы, поля, конструкторы и методы могут иметь один из четырех различных модификаторов доступа Java:
- Пункт списка
- частный
- по умолчанию (пакет)
- защищенный
- общественности
Из руководств по Управление доступом к членам класса:
Модификаторы уровня доступа определяют, могут ли другие классы использовать конкретное поле или вызывать определенный метод. Существует два уровня контроля доступа:
- На верхнем уровне - общедоступный или частный для пакета (без явного модификатора).
- На уровне члена - общедоступный, частный, защищенный или частный для пакета (без явного модификатора).
Класс может быть объявлен с модификатором public, и в этом случае этот класс будет виден всем классам повсюду. Если у класса нет модификатора (по умолчанию, также известного как package-private), он виден только в его собственном пакете.
В следующей таблице показан доступ к членам, разрешенный каждым модификатором.
╔═════════════╦═══════╦═════════╦══════════╦═══════╗ ║ Modifier ║ Class ║ Package ║ Subclass ║ World ║ ╠═════════════╬═══════╬═════════╬══════════╬═══════╣ ║ public ║ Y ║ Y ║ Y ║ Y ║ ║ protected ║ Y ║ Y ║ Y ║ N ║ ║ no modifier ║ Y ║ Y ║ N ║ N ║ ║ private ║ Y ║ N ║ N ║ N ║ ╚═════════════╩═══════╩═════════╩══════════╩═══════╝
Первый столбец данных указывает, имеет ли сам класс доступ к члену, определенному уровнем доступа. Как видите, класс всегда имеет доступ к своим собственным членам. Второй столбец указывает, имеют ли классы в том же пакете, что и класс (независимо от их происхождения), доступ к члену. Третий столбец указывает, имеют ли подклассы класса, объявленного вне этого пакета, доступ к члену. Четвертый столбец показывает, все ли классы имеют доступ к члену.
Уровни доступа влияют на вас двояко. Во-первых, когда вы используете классы из другого источника, например классы на платформе Java, уровни доступа определяют, какие члены этих классов могут использовать ваши собственные классы. Во-вторых, когда вы пишете класс, вам нужно решить, какой уровень доступа должен иметь каждая переменная-член и каждый метод в вашем классе.
Часто я осознавал, что запомнить основные концепции любого языка можно, создав аналогии из реального мира. Вот моя аналогия для понимания модификаторов доступа в Java:
Предположим, вы студент университета, и у вас есть друг, который приезжает к вам в гости на выходных. Предположим, что в центре кампуса стоит большая статуя основателя университета.
Когда вы приводите его в университетский городок, первое, что видите вы и ваш друг, - это статуя. Это означает, что любой, кто ходит по кампусу, может смотреть на статую без разрешения университета. Это делает статую ОБЩЕСТВЕННОЙ .
Затем вы хотите отвести друга к себе в общежитие, но для этого вам необходимо зарегистрировать его как посетителя. Это означает, что он получает пропуск (такой же, как у вас), чтобы попасть в различные здания на территории кампуса. Это сделает его карту доступа ЗАЩИЩЕННОЙ .
Ваш друг хочет войти в сеть Wi-Fi кампуса, но у него нет для этого учетных данных. Единственный способ, которым он может выйти в Интернет, - это если вы поделитесь с ним своим логином. (Помните, что каждый студент, поступающий в университет, также имеет эти учетные данные). Это сделает ваши учетные данные как БЕЗ МОДИФИКАТОРА .
Наконец, ваш друг хочет прочитать ваш отчет об успеваемости за семестр, который размещен на веб-сайте. Однако у каждого студента есть свой личный логин для доступа к этому разделу веб-сайта кампуса. Это сделает эти учетные данные ЧАСТНЫМИ .
Надеюсь это поможет!
Когда вы думаете о модификаторах доступа, просто думайте об этом так (применимо как к переменным , так и к методам ):
public
-> доступен отовсюду
private
-> доступен только в том же классе, где он объявлен
Теперь возникает путаница, когда дело доходит до default
и protected
default
-> Нет ключевого слова модификатора доступа. Это означает, что он доступен строго внутри пакета класса. Нигде за пределами этого пакета к нему нельзя получить доступ.
protected
-> Чуть менее строгий, чем default
, и, помимо тех же классов пакетов, к нему могут обращаться подклассы вне объявленного пакета .
Все дело в инкапсуляции (или, как сказал Джо Филлипс, наименьших знаний ).
Начните с наиболее ограничительных (частных) и посмотрите, не понадобятся ли вам позже менее ограничительные модификаторы.
Все мы используем модификаторы методов и членов, такие как private, public, ... но очень немногие разработчики делают то, что используют пакеты для логической организации кода.
Например: Вы можете поместить чувствительные методы безопасности в пакет «безопасности». Затем поместите общедоступный класс, который имеет доступ к некоторому коду, связанному с безопасностью, в этом пакете, но оставьте другие классы безопасности пакет закрытыми . Таким образом, другие разработчики смогут использовать общедоступный класс только извне этого пакета (если они не изменят модификатор). Это не функция безопасности, но будет направлять использование.
Outside world -> Package (SecurityEntryClass ---> Package private classes)
Другое дело, что классы, которые сильно зависят друг от друга, могут оказаться в одном пакете и в конечном итоге могут быть подвергнуты рефакторингу или объединению, если зависимость слишком сильна.
Если, наоборот, вы установите все как общедоступное , будет неясно, к чему следует или не следует обращаться, что может привести к написанию большого количества javadoc (который ничего не требует через компилятор ... ).
Мои два цента :)
частный:
class -> класс верхнего уровня не может быть частным. внутренние классы могут быть частными, доступными из того же класса.
переменная экземпляра -> доступна только в классе. Нет доступа вне класса.
частный пакет:
class -> класс верхнего уровня может быть частным для пакета. Он может быть доступен только из того же пакета. Ни из дополнительного пакета, ни из внешнего пакета.
переменная экземпляра -> доступна из того же пакета. Ни из дополнительного пакета, ни из внешнего пакета.
защищено:
class -> класс верхнего уровня не может быть защищен.
переменная экземпляра -> Доступна только в том же пакете или подпакете. Доступ может быть только вне пакета при расширении класса.
общедоступный:
класс -> доступен из пакета / подпакета / другого пакета
переменная экземпляра -> доступна из пакета / подпакета / другого пакета
Вот подробный ответ
https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md
общественности
Если член класса объявлен с помощью public, то к нему можно получить доступ из любого места.
защищенный
Если член класса объявлен с защищенным ключевым словом, то к нему можно получить доступ из тех же членов класса, вне членов класса в том же пакете и унаследованных членов класса. Если член класса защищен, то к нему НЕЛЬЗЯ получить доступ из внешнего класса пакета, если только внешний упакованный класс не унаследован, т.е. расширяет другой суперкласс пакета. Но член защищенного класса всегда доступен для одних и тех же классов пакетов, НЕ имеет значения, унаследован ли тот же класс пакета или НЕ
дефолт
В Java по умолчанию НЕ используется ключевое слово модификатора доступа. Если член класса объявлен без ключевого слова модификатора доступа, то в этом случае он считается членом по умолчанию. Член класса по умолчанию всегда доступен для тех же членов класса пакета. Но внешний член класса пакета НЕ может получить доступ к членам класса по умолчанию, даже если внешние классы являются подклассами, в отличие от защищенных членов.
частный
Если член класса объявлен с защищенным ключевым словом, то в этом случае он доступен ТОЛЬКО для тех же членов класса.
Когда мы говорим о модификаторах доступа, мы можем легко понять, что они включают очень простые правила.
Использование модификатора закрытого доступа в: - Только тот же класс
Использование модификатора доступа по умолчанию в: - Только тот же класс / те же подклассы пакета
Использование модификатора защищенного доступа: - в одном классе / в одном и том же подклассе пакета / в одном и том же пакете без - в подклассах / в разных подклассах пакетов
Модификатор открытого доступа используется в: — мы можем использовать где угодно (тот же класс / те же подклассы пакета / тот же пакет не-подклассы / разные подклассы пакета / разные пакеты не-подклассы)
Спецификаторы доступа в Java: в Java есть 4 спецификатора доступа, а именно частный, частный для пакета (по умолчанию), защищенный и открытый в порядке возрастания доступа.
Личное : Когда вы разрабатываете какой-либо класс и хотите, чтобы член этого класса не отображался за пределами этого класса, вы должны объявить его закрытым. к закрытым членам можно получить доступ только в том классе, в котором они определены, то есть охватывающем классе. Доступ к закрытым членам можно получить по ссылке "this", а также по другим экземплярам класса, включающим эти члены, но только в пределах определения этого класса.
Частный пакет (по умолчанию) : Этот спецификатор доступа будет предоставлять доступ, указанный спецификатором частного доступа, в дополнение к доступу, описанному ниже.
Когда вы разрабатываете какой-либо пакет и, следовательно, некоторый класс (скажем, Class1) в нем, вы можете использовать спецификатор доступа по умолчанию (не нужно упоминать явно), чтобы предоставить член внутри класса другим классам в вашем (том же) пакете. В этих других классах (в том же пакете) вы можете получить доступ к этим членам по умолчанию в экземпляре Class1. Также вы можете получить доступ к этим элементам по умолчанию в подклассах Class1, скажем Class2 (по этой ссылке, или в экземпляре Class1, или в экземпляре Class2).
По сути, в одном пакете вы можете получить доступ к элементам по умолчанию в экземпляре класса напрямую или по ссылке «this» в подклассах.
защищено : Этот спецификатор доступа будет предоставлять доступ, указанный спецификатором доступа частного пакета, в дополнение к доступу, описанному ниже.
Когда вы разрабатываете какой-либо пакет и, следовательно, некоторый класс (скажем, Class1) в нем, вы должны использовать защищенный спецификатор доступа для члена данных в Class1, если вы не хотите, чтобы этот член был доступен вне вашего пакета (скажем, в пакете потребителя из ваш пакет, то есть клиент, который использует ваши API) в целом, но вы хотите сделать исключение и разрешить доступ к этому члену только в том случае, если клиент пишет класс, скажем, Class2, который расширяет Class1. Таким образом, в общем случае защищенные члены будут доступны по ссылке this в производных классах, то есть в Class2, а также в явных экземплярах Class2.
Пожалуйста, обратите внимание:
- Вы не сможете получить доступ к унаследованному защищенному члену Class1 в Class2, если попытаетесь получить к нему доступ в явном экземпляре Class1, хотя он унаследован от него.
- Когда вы пишете другой класс Class3 в том же / другом пакете, который расширяет Class2, защищенный член из Class1 будет доступен по этой ссылке, а также по явному экземпляру Class3. Это будет верно для любой расширенной иерархии, т.е. защищенный член по-прежнему будет доступен по этой ссылке или экземпляру расширенного класса. Обратите внимание, что в Class3, если вы создаете экземпляр Class2, вы не сможете получить доступ к защищенному члену из Class1, хотя он унаследован.
Таким образом, защищенные члены могут быть доступны в других пакетах, только если некоторый класс из этого другого пакета расширяет класс, включающий этот защищенный член, а защищенный член доступен по ссылке 'this' или явным экземплярам расширенного класса внутри определение расширенного класса.
public : этот спецификатор доступа будет предоставлять доступ, указанный спецификатором защищенного доступа, в дополнение к доступу, описанному ниже.
Когда вы разрабатываете какой-то пакет и, следовательно, какой-то класс (скажем, Class1) в нем, вы должны использовать спецификатор публичного доступа для члена данных в Class1, если вы хотите, чтобы этот член был доступен в других пакетах на экземпляре Class1, созданном в каком-то классе другого упаковка. Обычно этот спецификатор доступа следует использовать, когда вы намереваетесь предоставить доступ к своему элементу данных миру без каких-либо условий.
Используйте private, если вы не хотите, чтобы ваши переменные/методы/классы были видны за пределами этого класса. используйте protected, если вы хотите, чтобы только дочерние элементы этого класса могли использовать эти переменные. используйте public, если вы хотите, чтобы переменная/класс/метод были доступны из любого места. используйте package-private, если вы хотите, чтобы ваши переменные/классы/методы использовались только внутри этого пакета.
< Сильный > Частный
- Методы, переменные и конструкторы
Методы, переменные и конструкторы, объявленные частными, доступны только внутри самого объявленного класса.
- Класс и интерфейс
Модификатор частного доступа - это самый ограничительный уровень доступа. Класс и интерфейсы не могут быть частными.
Примечание
Переменные, объявленные частными, могут быть доступны вне класса, если в классе присутствуют общедоступные методы получения. Переменные, методы и конструкторы, объявленные защищенными в суперклассе, могут быть доступны только подклассам в другом пакете или любому классу в пакете класса защищенных членов.
< Сильный > Защищенный
- Класс и интерфейс
Модификатор защищенного доступа нельзя применять к классу и интерфейсам.
Методы и поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.
Примечание
Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, предотвращая попытки несвязанного класса использовать его.
< Сильный > Public
К классу, методу, конструктору, интерфейсу и т. д., объявленным общедоступным, можно получить доступ из любого другого класса.
Следовательно, поля, методы и блоки, объявленные внутри открытого класса, могут быть доступны из любого класса, принадлежащего Java Universe.
- Различные пакеты
Однако, если открытый класс, к которому мы пытаемся получить доступ, находится в другом пакете, то открытый класс все равно необходимо импортировать.
Из-за наследования классов все общедоступные методы и переменные класса наследуются его подклассами.
По умолчанию - без ключевого слова:
Модификатор доступа по умолчанию означает, что мы явно не объявляем модификатор доступа для класса, поля, метода и т. д.
- В одном пакете
Переменная или метод, объявленные без модификатора управления доступом, доступны любому другому классу в том же пакете. Поля в интерфейсе неявно являются общедоступными static final, а методы интерфейса по умолчанию являются общедоступными.
Примечание
Мы не можем переопределить статические поля. Если вы попытаетесь переопределить, это не покажет никаких ошибок, но это не сработает, за исключением нас.
Связанные ответы
Ссылки ссылки
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html http://www.tutorialspoint.com/java/java_access_modifiers.htm
Следующая блок-схема объясняет, как наследуются элементы данных базового класса , когда режим доступа производного класса является закрытым .
Примечание. Объявление элементов данных со спецификатором частного доступа называется скрытием данных .
Источник: Спецификаторы доступа - частный, общедоступный и защищенный
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.
private
скрывается от других классов в пакете.public
предоставляется классам вне пакета.protected
- это версияpublic
, ограниченная только подклассами.protected
делает метод доступным также из всего пакета. Эта глупость в модели видимости Java нарушает цельprotected
.protected
или без него. В качестве модификатора доступа все, что делаетprotected
, - это предоставление доступа подклассам вне пакета.protected
- и я цитирую - «это версия public, ограниченная только подклассами», что неверно, по вашему собственному признанию, поскольку protected также разрешает доступ через весь пакет (следовательно, он не ограничить доступ к подклассам.)protected-package
для тех редких случаев, когда он нам действительно нужен, оставивprotected
эквивалентным защищенной версии C ++.