В Java, есть четкие правила о том, когда использовать каждый из модификаторов доступа, а именно : по умолчанию (частный пакет), public
, protected
и private
, делая class
и interface
и дело с наследованием?
Официальный учебник может быть полезным для вас.
______________________________________________________________ | │ Класс │ Пакет │ Подкласс │ Подкласс │ Мир | | Same │ │ (тот же pkg) │ (diff pkg) │ | | ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── | | публичный │ + │ + │ + │ + │ + | | ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── | | защищенный │ + │ + │ + │ + │ | | ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── | | без модификаторов│ + │ + │ + │ │ | | ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── | | частный │ + │ │ │ │ | | ___________ | _______ | _________ | __________ | __________ | ________ | +: доступно пусто: недоступно
private
члены могут быть просмотрены / использованы любым классом / статическим методом в одном и том же исходном файле. MyClass
и я делаю, у AnotherClass extends MyClass
меня будет доступ ко всем защищенным и открытым методам и свойствам изнутри AnotherClass
. Если я MyClass myClass = new MyClass();
в AnotherClass
где - нибудь - скажем , конструктор - я буду иметь доступ только к публичным методам , если он находится в другом пакете. Обратите внимание, что если я это сделаю, = new MyClass() { @Override protected void protectedMethod() { //some logic } };
то я получу доступ к защищенным методам, но это то же самое, что и расширение, но вместо этого встроенное. protected
что (на самом деле, это довольно сложный модификатор доступа для полного понимания - большинство людей, которые думают, что знают, что на protected
самом деле означает, не знают ). Кроме того, как отметил Богемян, он не отвечает на вопрос - он ничего не говорит о том, когда использовать каждый модификатор доступа. По моему мнению, этот ответ не достаточно плох, чтобы понизить, но близко. Но более 4000 голосов? Как это случилось? Простое правило. Начните с объявления всего частного. И затем прогресс по отношению к публике, когда потребности возникают, и дизайн оправдывает это.
Представляя участников, спросите себя, выставляете ли вы выбор представлений или выбор абстракций. Первое - это то, чего вы хотите избежать, так как оно вводит слишком много зависимостей от реального представления, а не от его наблюдаемого поведения.
Как правило, я стараюсь избегать переопределения реализаций методов путем создания подклассов; слишком легко испортить логику. Объявите абстрактно защищенные методы, если вы собираетесь переопределить его.
Кроме того, используйте аннотацию @Override при переопределении, чтобы предотвратить поломку при рефакторинге.
Разницу можно найти в уже предоставленных ссылках, но какую из них использовать обычно сводится к «Принципу наименьшего знания». Позвольте только наименьшую видимость, которая необходима.
(Предостережение: я не программист на Java, я программист на Perl. У Perl нет формальной защиты, поэтому, возможно, я так хорошо понимаю проблему :))
Частный
Как вы думаете, только класс, в котором он объявлен, может видеть его.
Пакет Приват
Может быть увидено и использовано только пакетом, в котором оно было объявлено. Это значение по умолчанию в Java (что некоторые считают ошибкой).
защищенный
Пакет Private + может просматриваться подклассами или членами пакета.
общественного
Каждый может это увидеть.
опубликованный
Видимо за пределами кода, который я контролирую. (Хотя это не синтаксис Java, это важно для этого обсуждения).
C ++ определяет дополнительный уровень, называемый «друг», и чем меньше вы знаете об этом, тем лучше.
Когда вы должны использовать что? Вся идея заключается в инкапсуляции, чтобы скрыть информацию. Как можно больше вы хотите скрыть детали того, как что-то делается от ваших пользователей. Почему? Потому что тогда вы можете изменить их позже и не нарушать чей-либо код. Это позволяет оптимизировать, реорганизовывать, перепроектировать и исправлять ошибки, не беспокоясь о том, что кто-то использовал этот код, который вы только что пересмотрели.
Таким образом, эмпирическое правило заключается в том, чтобы делать вещи только такими видимыми, какими они должны быть. Начните с частного и добавьте больше видимости по мере необходимости. Обнародуйте только то, что абсолютно необходимо знать пользователю, каждая деталь, которую вы публикуете, ограничивает вашу способность перепроектировать систему.
Если вы хотите, чтобы пользователи могли настраивать поведение, а не публиковать внутренние данные, чтобы они могли их переопределить, часто лучше добавить эти свойства в объект и сделать этот интерфейс общедоступным. Таким образом, они могут просто подключить новый объект. Например, если вы писали проигрыватель компакт-дисков и хотели, чтобы бит "go find info об этом компакт-диске" был настраиваемым, вместо того, чтобы делать эти методы общедоступными, вы бы поместили всю эту функциональность в свой собственный объект и сделали бы доступным только объект-получатель / установщик объекта , Таким образом, скупость на разоблачение своих внутренностей способствует хорошей композиции и разделению проблем.
Лично я придерживаюсь только «частного» и «общественного». У многих ОО-языков это есть. «Защищенный» может быть удобен, но это действительно обман. Как только интерфейс становится более приватным, он становится вне вашего контроля, и вы должны искать код других людей, чтобы найти применение.
Вот тут и возникает идея «опубликованного». Изменение интерфейса (рефакторинг) требует, чтобы вы нашли весь код, который его использует, и изменили его тоже. Если интерфейс является частным, то нет проблем. Если он защищен, вы должны найти все свои подклассы. Если это общедоступно, вы должны найти весь код, который использует ваш код. Иногда это возможно, например, если вы работаете над корпоративным кодом, предназначенным только для внутреннего использования, не имеет значения, является ли интерфейс общедоступным. Вы можете получить весь код из корпоративного хранилища. Но если интерфейс «опубликован», если есть код, использующий его вне вашего контроля, то вы попадаете в ловушку. Вы должны поддерживать этот интерфейс или рисковать нарушением кода. Даже защищенные интерфейсы можно считать опубликованными (вот почему я не
Многие языки считают иерархическую природу публичного / защищенного / частного слишком ограничивающей и не соответствующей действительности. Для этого есть концепция класс черты , но это еще одно шоу.
friend
хорошо для определения особых отношений между классами. Это позволяет превосходную инкапсуляцию во многих случаях при правильном использовании. Например, он может использоваться привилегированным классом фабрики для внедрения внутренних зависимостей в составной тип. У него плохое имя, потому что люди, которые не заботятся о правильном поддержании хорошо спроектированной объектной модели, могут злоупотреблять ею, чтобы облегчить свою рабочую нагрузку. Ответ Дэвида обеспечивает значение каждого модификатора доступа. Что касается того, когда использовать каждый из них, я бы предложил обнародовать все классы и методы каждого класса, предназначенные для внешнего использования (его API), а все остальное - приватно.
Со временем вы поймете, когда делать некоторые классы закрытыми для пакетов, а когда объявлять определенные методы защищенными для использования в подклассах.
Эта страница хорошо описывает модификатор защищенного доступа и доступа по умолчанию
.... Защищенный: модификатор защищенного доступа немного сложен, и вы можете сказать, что это расширенный вариант модификатора доступа по умолчанию. Защищенные члены такие же, как и члены по умолчанию, если речь идет о доступе в том же пакете. Разница в том, что защищенные члены также доступны для подклассов класса, в котором объявлен член, которые находятся вне пакета, в котором присутствует родительский класс.
Но эти защищенные члены «доступны вне пакета только по наследству». т.е. вы можете получить доступ к защищенному члену класса в его подклассе, представленном в каком-либо другом пакете, напрямую, как если бы этот член присутствовал в самом подклассе. Но этот защищенный член не будет доступен в подклассе за пределами пакета, используя ссылку родительского класса. ....
Это на самом деле немного сложнее, чем простая сетка показывает. Сетка говорит вам, разрешен ли доступ, но что именно представляет собой доступ? Кроме того, уровни доступа взаимодействуют с вложенными классами и наследованием сложным образом.
Доступ по умолчанию (определяемый отсутствием ключевого слова) также называется package-private . Исключение: в интерфейсе нет модификатора, означающего публичный доступ; запрещены модификаторы, кроме public. Константы enum всегда общедоступны.
Резюме
Разрешен ли доступ к участнику с этим спецификатором доступа?
- Member is
private
: Только если member определен в том же классе, что и вызывающий код. - Участник является частным пакетом: только в том случае, если вызывающий код находится в пакете, который непосредственно входит в состав участника.
- Member is
protected
: тот же пакет, или если member определен в суперклассе класса, содержащего вызывающий код. - Участник
public
: Да.
Какие спецификаторы доступа применяются к
Локальные переменные и формальные параметры не могут принимать спецификаторы доступа. Так как они по своей природе недоступны извне в соответствии с правилами области видимости, они фактически являются частными.
Для классов в верхней области public
разрешены только и package-private. Такой дизайн, по- видимому , потому protected
и private
будет излишним на уровне пакета (нет наследования пакетов).
Все спецификаторы доступа возможны для членов класса (конструкторы, методы и статические функции-члены, вложенные классы).
Связанный: Доступность Класса Java
порядок
Спецификаторы доступа могут быть строго упорядочены
public> protected> package-private> private
Это означает, что 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
Некоторые связанные вопросы:
Очень коротко
public
: доступно везде.protected
: доступно классам одного пакета и подклассам, находящимся в любом пакете.- по умолчанию (модификатор не указан): доступен для классов одного и того же пакета.
private
: доступно только в одном классе.
Как правило большого пальца:
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 |
+—————————————————+————————————+———————————+
____________________________________________________________________
| 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
помеченная вещь . Наиболее неправильно понят модификатор доступа в 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
) [Это может быть включено в контекст №. 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 } }
Object#clone()
это пример protected
члена. super.foo()
и первой неверной ситуацией f.foo()
? protected
. К сожалению, все остальные ответы на этой странице, которые определяют protected
это, немного ошибочны. Частный
- Методы, переменные и конструкторы
Методы, переменные и конструкторы, которые объявлены закрытыми, могут быть доступны только внутри самого объявленного класса.
- Класс и интерфейс
Модификатор частного доступа является наиболее ограниченным уровнем доступа. Класс и интерфейсы не могут быть приватными.
Запись
Переменные, которые объявлены закрытыми, могут быть доступны вне класса, если в классе присутствуют общедоступные методы получения. Переменные, методы и конструкторы, которые объявлены защищенными в суперклассе, могут быть доступны только подклассам в другом пакете или любом классе в пакете класса защищенных членов.
защищенный
- Класс и интерфейс
Модификатор защищенного доступа нельзя применять к классу и интерфейсам.
Методы, поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.
Запись
Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, в то же время предотвращая попытки его использования не связанным классом.
общественного
Класс, метод, конструктор, интерфейс и т. Д., Объявленные как public, могут быть доступны из любого другого класса.
Поэтому к полям, методам, блокам, объявленным внутри открытого класса, можно получить доступ из любого класса, принадлежащего Java Universe.
- Разные пакеты
Однако если публичный класс, к которому мы пытаемся получить доступ, находится в другом пакете, тогда публичный класс все равно необходимо импортировать.
Из-за наследования классов все открытые методы и переменные класса наследуются его подклассами.
По умолчанию - нет ключевого слова:
Модификатор доступа по умолчанию означает, что мы не объявляем явно модификатор доступа для класса, поля, метода и т. Д.
- В рамках одного пакета
Переменная или метод, объявленные без какого-либо модификатора контроля доступа, доступны любому другому классу в том же пакете. Поля в интерфейсе неявно являются public static final, а методы в интерфейсе по умолчанию являются public.
Запись
Мы не можем переопределить статические поля. Если вы пытаетесь переопределить, это не показывает никакой ошибки, но это не работает, что мы кроме.
Похожие ответы
Ссылки ссылки
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html http://www.tutorialspoint.com/java/java_access_modifiers.htm
Частный : ограниченный доступ только к классу
По умолчанию (без модификатора) : ограниченный доступ к классу и пакету
Защищено : ограниченный доступ к классу, пакету и подклассам (как внутри, так и снаружи пакета)
Общедоступный : Доступен для класса, пакета (всех) и подклассов ... Короче говоря, везде.
Public Protected Default и private являются модификаторами доступа.
Они предназначены для инкапсуляции или скрытия и отображения содержимого класса.
- Класс может быть публичным или по умолчанию
- Члены класса могут быть открытыми, защищенными, стандартными или закрытыми.
Закрытый недоступен вне класса. По умолчанию доступен только в пакете. Защищено как в пакете, так и в любом классе, который его расширяет. Общественность открыта для всех.
Обычно переменные-члены определяются как частные, но методы-члены являются открытыми.
Default
не является модификатором доступа, а два других написаны с ошибками. Модификаторы доступа предназначены для ограничения доступа на нескольких уровнях.
Публичный: Это в основном так просто, как вы можете получить доступ из любого класса, находится ли он в одном пакете или нет.
Для доступа, если вы находитесь в том же пакете, вы можете получить доступ напрямую, но если вы находитесь в другом пакете, то вы можете создать объект класса.
По умолчанию: он доступен в одном пакете из любого класса пакета.
Для доступа вы можете создать объект класса. Но вы не можете получить доступ к этой переменной за пределами пакета.
Защищено: вы можете получить доступ к переменным в том же пакете, а также к подклассу в любом другом пакете. так что в основном это по умолчанию + унаследованное поведение.
Для доступа к защищенному полю, определенному в базовом классе, вы можете создать объект дочернего класса.
Частный: это может быть доступ в том же классе.
В нестатических методах вы можете получить доступ напрямую из-за этой ссылки (также в конструкторах), но для доступа в статических методах вам нужно создать объект класса.
Видна на упаковке. По умолчанию. Модификаторы не нужны.
Доступно только для класса ( личное ).
Видимый миру ( публичный ).
Доступен для пакета и всех подклассов ( защищен ).
Переменные и методы могут быть объявлены без каких-либо вызываемых модификаторов. Примеры по умолчанию:
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;
}
}
Модификатор публичного доступа - публичный:
Класс, метод, конструктор, интерфейс и т. Д., Объявленные как public, могут быть доступны из любого другого класса. Поэтому к полям, методам, блокам, объявленным внутри открытого класса, можно получить доступ из любого класса, принадлежащего юниверсу Java.
Однако если публичный класс, к которому мы пытаемся получить доступ, находится в другом пакете, тогда публичный класс все равно необходимо импортировать.
Из-за наследования классов все открытые методы и переменные класса наследуются его подклассами.
Пример:
public void cal(){
}
Модификатор защищенного доступа - protected:
Переменные, методы и конструкторы, которые объявлены защищенными в суперклассе, могут быть доступны только подклассам в другом пакете или любом классе в пакете класса защищенных членов.
Модификатор защищенного доступа нельзя применять к классу и интерфейсам. Методы, поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.
Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, в то же время предотвращая попытки его использования не связанным классом.
class Van{
protected boolean speed(){
}
}
class Car{
boolean speed(){
}
}
общедоступный - доступен из любой точки приложения.
по умолчанию - доступно из пакета.
защищенный - доступный из пакета и подклассов в другом пакете. также
частный - доступен только для своего класса.
Вот лучшая версия таблицы. (Доказательство будущего с колонкой для модулей.)
Пояснения
Частный член (
i
) является только доступным в том же классе , как она была объявлена.Элемент без модификатора доступа (
j
) доступен только внутри классов в одном пакете.Защищенный член (
k
) доступен во всех классах в одном пакете и в подклассах в других пакетах.Общественный элемент (
l
) доступен для всех классов (если он не находится в модуле , который не экспортировать пакет, который объявлен в).
Какой модификатор выбрать?
Модификаторы доступа - это инструмент, помогающий предотвратить случайное нарушение инкапсуляции (*) . Спросите себя, хотите ли вы, чтобы член был чем-то внутренним для класса, пакета, иерархии классов или не внутренним, и выберите соответствующий уровень доступа.
Примеры:
- Поле,
long internalCounter
вероятно, должно быть закрытым, поскольку оно изменчиво и является деталью реализации. - Класс, который должен создаваться только в фабричном классе (в том же пакете), должен иметь конструктор с ограниченным пакетом, так как не должно быть возможности вызывать его напрямую из пакета.
- Внутренний
void beforeRender()
метод, вызываемый непосредственно перед рендерингом и используемый как ловушка в подклассах, должен быть защищен. void saveGame(File dst)
Метод , который вызывается из кода GUI должен быть публичным.
Модификаторы доступа в 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();
}
}
Вывод: Привет
Примечание: это всего лишь дополнение к принятому ответу.
Это связано с модификаторами доступа Java .
Из модификаторов доступа Java :
Модификатор доступа Java определяет, какие классы могут обращаться к данному классу и его полям, конструкторам и методам. Модификаторы доступа могут быть указаны отдельно для класса, его конструкторов, полей и методов. Модификаторы доступа Java также иногда упоминаются в повседневной речи как спецификаторы доступа Java, но правильное имя - модификаторы доступа Java. Классы, поля, конструкторы и методы могут иметь один из четырех различных модификаторов доступа Java:
- Пункт списка
- частный
- по умолчанию (пакет)
- защищенный
- общественности
Из управления доступом к членам класса учебники:
Модификаторы уровня доступа определяют, могут ли другие классы использовать конкретное поле или вызывать определенный метод. Существует два уровня контроля доступа:
- На верхнем уровне - public или package-private (без явного модификатора).
- На уровне участника - открытый, закрытый, защищенный или закрытый для пакета (без явного модификатора).
Класс может быть объявлен с модификатором public, и в этом случае этот класс виден всем классам везде. Если класс не имеет модификатора (по умолчанию, также известного как package-private), он виден только в своем собственном пакете
В следующей таблице показан доступ к элементам, разрешенным каждым модификатором.
╔═════════════╦═══════╦═════════╦══════════╦═══════╗ ║ Modifier ║ Class ║ Package ║ Subclass ║ World ║ ╠═════════════╬═══════╬═════════╬══════════╬═══════╣ ║ public ║ Y ║ Y ║ Y ║ Y ║ ║ protected ║ Y ║ Y ║ Y ║ N ║ ║ no modifier ║ Y ║ Y ║ N ║ N ║ ║ private ║ Y ║ N ║ N ║ N ║ ╚═════════════╩═══════╩═════════╩══════════╩═══════╝
Первый столбец данных указывает, имеет ли сам класс доступ к члену, определенному уровнем доступа. Как видите, класс всегда имеет доступ к своим собственным членам. Во втором столбце указано, имеют ли классы в том же пакете, что и класс (независимо от их происхождения), доступ к члену. Третий столбец указывает, имеют ли подклассы класса, объявленного вне этого пакета, доступ к члену. В четвертом столбце указано, все ли классы имеют доступ к члену.
Уровни доступа влияют на вас двумя способами. Во-первых, когда вы используете классы, которые приходят из другого источника, такого как классы на платформе Java, уровни доступа определяют, какие члены этих классов могут использовать ваши собственные классы. Во-вторых, когда вы пишете класс, вам нужно решить, какой уровень доступа должна иметь каждая переменная-член и каждый метод в вашем классе.
Часто я осознавал, что запоминание основных понятий любого языка стало возможным благодаря созданию реальных аналогий. Вот моя аналогия для понимания модификаторов доступа в Java:
Давайте предположим, что вы студент университета и у вас есть друг, который приедет к вам на выходные. Предположим, что в центре кампуса находится большая статуя основателя университета.
Когда вы приводите его в кампус, первое, что вы и ваш друг видите, это эта статуя. Это означает, что любой, кто ходит по кампусу, может посмотреть на статую без разрешения университета. Это делает статую как PUBLIC .
Далее вы хотите отвести своего друга в общежитие, но для этого вам необходимо зарегистрировать его в качестве посетителя. Это означает, что он получает пропуск (такой же, как у вас), чтобы попасть в различные здания в кампусе. Это сделало бы его карту доступа ЗАЩИЩЕННОЙ .
Ваш друг хочет войти в кампус Wi-Fi, но не имеет никаких учетных данных для этого. Единственный способ, которым он может выйти в Интернет, - это если вы поделитесь с ним своим логином. (Помните, что каждый студент, который поступает в университет, также имеет эти учетные данные). Это сделало бы ваши учетные данные для входа без модификатора .
Наконец, ваш друг хочет прочитать ваш отчет о проделанной работе за семестр, который размещен на сайте. Тем не менее, у каждого студента есть свой личный логин для доступа к этому разделу сайта кампуса. Это сделало бы эти полномочия как ЧАСТНЫЕ .
Надеюсь это поможет!
Когда вы думаете о модификаторах доступа, просто подумайте об этом следующим образом (относится как к переменным, так и к методам ):
public
-> доступный из любого места
private
-> доступный только в том же классе, где он объявлен
Теперь возникает путаница , когда речь идет default
иprotected
default
-> Ключевое слово модификатора доступа отсутствует. Это означает, что это доступно строго в пакете класса. Нигде за пределами этого пакета к нему нет доступа.
protected
-> Чуть менее строгие, чем default
те же классы пакетов, но и те же классы, к которым он может получить доступ подклассами вне объявленного пакета .
Все дело в инкапсуляции (или, как сказал Джо Филлипс, минимум знаний ).
Начните с самого ограничительного (частного) и посмотрите, не понадобятся ли вам в дальнейшем менее ограничительные модификаторы.
Мы все используем модификаторы методов и членов, такие как private, public, ... но одна вещь, которую делают немногие разработчики, - это использование пакетов для логической организации кода.
Например: вы можете поместить чувствительные методы безопасности в пакет «security». Затем поместите открытый класс, который получает доступ к некоторому коду, связанному с безопасностью, в этом пакете, но оставьте пакет других классов безопасности закрытым . Таким образом, другие разработчики смогут использовать общедоступный класс только за пределами этого пакета (если они не изменят модификатор). Это не функция безопасности, но будет направлять использование.
Outside world -> Package (SecurityEntryClass ---> Package private classes)
Другое дело, что классы, которые сильно зависят друг от друга, могут оказаться в одном и том же пакете и в конечном итоге могут быть реорганизованы или объединены, если зависимость слишком сильна.
Если, наоборот, вы сделаете все общедоступным , неясно, к чему следует или не нужно обращаться, что может привести к написанию большого количества javadoc (который ничего не навязывает через компилятор ...).
общественности
Если член класса объявлен с общедоступным, то к нему можно получить доступ из любого места
защищенный
Если член класса объявлен с защищенным ключевым словом, то к нему можно получить доступ из тех же членов класса, вне членов класса в том же пакете и унаследованных членов класса. Если член класса защищен, то к нему нельзя получить доступ извне класса пакета, если только внешний упакованный класс не унаследован, то есть расширяет суперкласс другого пакета. Но защищенный член класса всегда доступен для одних и тех же классов пакетов, это НЕ имеет значения, наследуется ли один и тот же класс пакета или НЕТ
дефолт
В Java по умолчанию НЕ используется ключевое слово модификатора доступа. Если член класса объявлен без ключевого слова модификатора доступа, то в этом случае он считается членом по умолчанию. Член класса по умолчанию всегда доступен тем же членам класса пакета. Но внешний член класса пакета НЕ может получить доступ к членам класса по умолчанию, даже если внешние классы являются подклассами в отличие от защищенных членов.
частный
Если член класса объявлен с ключевым словом защищен, то в этом случае он доступен ТОЛЬКО для тех же членов класса
После блок - схема объясняет , как данные члены базового класса являются унаследовали , когда производный класс режим доступа частных .
Примечание. Объявление членов данных с помощью частного спецификатора доступа называется скрытием данных.
Источник: Спецификаторы доступа - частный, публичный и защищенный
Мои два цента :)
частный:
класс -> класс верхнего уровня не может быть закрытым. внутренние классы могут быть приватными, которые доступны из того же класса.
переменная экземпляра -> доступна только в классе. Не может получить доступ за пределами класса.
пакет-частное:
class -> класс верхнего уровня может быть закрытым для пакета. Он может быть доступен только из одного пакета. Не из дополнительного пакета, не из внешнего пакета.
переменная экземпляра -> доступна из того же пакета. Не из дополнительного пакета, не из внешнего пакета.
защищенный:
класс -> класс верхнего уровня не может быть защищен.
переменная экземпляра -> Доступна только в том же пакете или подпакете. Может быть доступ только вне пакета при расширении класса.
общественности:
класс -> доступный из пакета / подпакета / другого пакета
переменная экземпляра -> доступная из пакета / подпакета / другого пакета
Вот подробный ответ
https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md
Доступ Java изменяет, который вы можете использовать
Модификатор доступа может быть применим для class
, field
[О] , method
. Попробуйте получить доступ, создать подкласс или переопределить это.
- Доступ к
field
илиmethod
черезclass
. - Наследование. Преемник
class
(подкласс) модификатор доступа может быть любым. Преемникmethod
(переопределить) модификатор доступа должен быть таким же или расширить его
Класс верхнего уровня (область первого уровня) может быть public
и default
. Nested class
[О] может иметь любой из них
package
не относится к иерархии пакетов
Спецификаторы доступа в Java: в java есть 4 спецификатора доступа: приватный, закрытый (по умолчанию), защищенный и общедоступный в порядке возрастания доступа.
Приватный : Когда вы разрабатываете какой-то класс и хотите, чтобы член этого класса не был представлен вне этого класса, вы должны объявить его как закрытый. частные члены могут быть доступны только в классе, где они определены, т.е. в классе. Доступ к закрытым членам можно получить по ссылке «this», а также по другим экземплярам класса, содержащим эти члены, но только в пределах определения этого класса.
Частный пакет (по умолчанию) : этот спецификатор доступа предоставит доступ, указанный спецификатором частного доступа, в дополнение к описанному ниже доступу.
Когда вы разрабатываете какой-то пакет и, следовательно, какой-то класс (скажем, Class1) внутри него, вы можете использовать спецификатор доступа по умолчанию (не упоминать явно), чтобы выставить член внутри класса, другим классам в вашем (том же) пакете. В этих других классах (в том же пакете) вы можете получить доступ к этим элементам по умолчанию в экземпляре Class1. Также вы можете получить доступ к этим элементам по умолчанию в подклассах Class1, скажем Class2 (по этой ссылке или в экземпляре Class1 или в экземпляре Class2).
По сути, в одном и том же пакете вы можете получить доступ к членам по умолчанию непосредственно в экземпляре класса или по ссылке this в подклассах.
protected : этот спецификатор доступа предоставит доступ, указанный спецификатором доступа к частному пакету, в дополнение к описанному ниже доступу.
Когда вы разрабатываете некоторый пакет и, следовательно, некоторый класс (скажем, Class1) внутри него, вам следует использовать спецификатор защищенного доступа для члена данных в Class1, если вы не хотите, чтобы этот член был доступен вне вашего пакета (скажем, в пакете потребителя ваш пакет, т.е. клиент, который использует ваши API) в целом, но вы хотите сделать исключение и разрешить доступ к этому члену, только если клиент пишет класс, скажем, Class2, который расширяет Class1. Таким образом, в общем случае защищенные члены будут доступны по ссылке «this» в производных классах, т.е. Class2, а также в явных экземплярах Class2.
Пожалуйста, обратите внимание:
- Вы не сможете получить доступ к унаследованному защищенному члену Class1 в Class2, если попытаетесь получить к нему доступ в явном экземпляре Class1, хотя он наследуется в нем.
- Когда вы пишете другой класс Class3 в том же / другом пакете, который расширяет Class2, защищенный член из Class1 будет доступен по этой ссылке, а также по явному экземпляру Class3. Это будет справедливо для любой расширенной иерархии, т.е. защищенный член будет по-прежнему доступен для этой ссылки или экземпляра расширенного класса. Обратите внимание, что в Class3, если вы создадите экземпляр Class2, вы не сможете получить доступ к защищенному члену из Class1, хотя он наследуется.
Итак, суть в том, что к защищенным членам можно получить доступ в других пакетах, только если некоторый класс из этого другого пакета расширяет класс, включающий этот защищенный член, и защищенный член доступен по ссылке «this» или явным экземплярам расширенного класса, в пределах определения расширенного учебный класс.
public : этот спецификатор доступа предоставит доступ, указанный спецификатором защищенного доступа, в дополнение к описанному ниже доступу.
Когда вы разрабатываете какой-то пакет и, следовательно, некоторый класс (скажем, Class1) внутри него, вы должны использовать общедоступный спецификатор для члена данных в Class1, если вы хотите, чтобы этот член был доступен в других пакетах на экземпляре Class1, созданном в каком-то другом классе. пакет. По сути, этот спецификатор доступа следует использовать, когда вы намереваетесь представить свой элемент данных миру без каких-либо условий.
private
скрывается от других классов в пакете.public
подвергает классам вне пакета.protected
версияpublic
ограничена только подклассами.protected
этот метод также доступен из всего пакета. Эта глупость в модели видимости Java нарушает цельprotected
.protected
. В качестве модификатора доступа все, чтоprotected
нужно сделать - это открыть подклассы вне пакета.protected
- и я цитирую - «версия публичного доступа, ограниченная только подклассами», что неверно по вашему собственному допуску, так как защищенный также разрешает доступ через весь пакет (следовательно, он не ограничивает доступ к подклассам. )protected-package
для тех редких случаев, когда нам это действительно требовалось, оставляяprotected
эквивалент эквивалентной версии C ++ защищенной.