В чем разница между общедоступным, защищенным, частным и частным в Java?
3172
В Java, есть четкие правила о том, когда использовать каждый из модификаторов доступа, а именно : по умолчанию (частный пакет), public, protectedи private, делая classи interfaceи дело с наследованием?
privateскрывается от других классов в пакете. publicподвергает классам вне пакета. protectedверсия publicограничена только подклассами.
Museful
87
@Tennenrishin - Нет; В отличие от C ++, в Java protectedэтот метод также доступен из всего пакета. Эта глупость в модели видимости Java нарушает цель protected.
Николас Барбулеско
35
@Nicolas Это доступно из всего пакета, с или без protected. В качестве модификатора доступа все, что protectedнужно сделать, это предоставить подклассам вне пакета.
Музейный
15
@tennenrishin - ну, вот что сказал Николас ... и вы просто повторяете это сейчас. Первоначально вы сказали, что protected- и я цитирую - «версия публичного доступа, ограниченная только подклассами», что не соответствует действительности по вашему собственному допущению, так как защищенный также разрешает доступ через весь пакет (то есть он не ограничивает доступ к подклассам. )
luis.espinal
10
Я также согласен с Николасом в том, что режим защищенного доступа в Java является идиотским. Случилось так, что Java объединила классификаторы ограничения доступа по горизонтали (решетке) и по вертикали. Область действия по умолчанию - ограничение по горизонтали / решетке, причем решетка является пакетом. Публичность - это еще одно горизонтальное ограничение, где решеткой является весь мир. Частные и (C ++) защищенные являются вертикальными. Было бы лучше, если бы у нас был сквозной доступ, скажем, protected-packageдля тех редких случаев, когда он нам действительно нужен, оставляя protectedэквивалент эквивалентной версии C ++ защищенной.
Приведенная выше таблица неверна, поскольку даже privateчлены могут быть просмотрены / использованы любым классом / статическим методом в одном и том же исходном файле.
Усаги Миямото
5
Доступ к защищенному члену возможен только из подкласса одного и того же пакета, но не из подкласса из другого пакета. В приведенной выше таблице должна быть поправка
Никс
2
Мир в вашем проекте . Я должен объяснить дальше. Библиотеки находятся в вашем проекте, и если вы создаете библиотеку, они также предоставляют эти публичные классы и методы. Так что говорить только в рамках вашего проекта немного не так. «Все, что использует это» - лучшее описание.
adprocas
3
Например, если у меня есть MyClassи я делаю, у AnotherClass extends MyClassменя будет доступ ко всем защищенным и открытым методам и свойствам изнутри AnotherClass. Если я MyClass myClass = new MyClass();в AnotherClassгде - нибудь - скажем , конструктор - я буду иметь доступ только к публичным методам , если он находится в другом пакете. Обратите внимание, что если я это сделаю, = new MyClass() { @Override protected void protectedMethod() { //some logic } };то я получу доступ к защищенным методам, но это то же самое, что и расширение, но вместо этого встроенное.
adprocas
3
К сожалению, этот ответ является грубым упрощением. Реальность немного сложнее, особенно если учесть, protectedчто (на самом деле это довольно сложный модификатор доступа для полного понимания - большинство людей, которые думают, что знают, что на protectedсамом деле означает, не знают ). Кроме того, как отметил Богемян, он не отвечает на вопрос - он ничего не говорит о том, когда использовать каждый модификатор доступа. По моему мнению, этот ответ не достаточно плох, чтобы понизить, но близко. Но более 4000 голосов? Как это случилось?
Дауд ибн Карим
483
(Предостережение: я не программист на Java, я программист на Perl. У Perl нет формальной защиты, поэтому, возможно, поэтому я так хорошо понимаю проблему :))
Частный
Как вы думаете, только класс, в котором он объявлен, может видеть его.
Пакет Приват
Его может видеть и использовать только тот пакет, в котором он был объявлен. Это значение по умолчанию в Java (что некоторые считают ошибкой).
защищенный
Пакет Private + может просматриваться подклассами или членами пакета.
Видимо за пределами кода, который я контролирую. (Хотя это не синтаксис Java, это важно для этого обсуждения).
C ++ определяет дополнительный уровень, называемый «друг», и чем меньше вы знаете об этом, тем лучше.
Когда вы должны использовать что? Вся идея заключается в инкапсуляции, чтобы скрыть информацию. Как можно больше вы хотите скрыть детали того, как что-то делается от ваших пользователей. Почему? Потому что тогда вы можете изменить их позже и не нарушать чей-либо код. Это позволяет оптимизировать, реорганизовывать, перепроектировать и исправлять ошибки, не беспокоясь о том, что кто-то использовал этот код, который вы только что пересмотрели.
Таким образом, эмпирическое правило состоит в том, чтобы делать вещи только такими видимыми, какими они должны быть. Начните с частного и добавьте больше видимости по мере необходимости. Обнародуйте только то, что абсолютно необходимо знать пользователю, каждая деталь, которую вы публикуете, ограничивает вашу способность перепроектировать систему.
Если вы хотите, чтобы пользователи могли настраивать поведение, а не публиковать внутренние данные, чтобы они могли их переопределить, часто лучше вставить эти внутренности в объект и сделать этот интерфейс общедоступным. Таким образом, они могут просто подключить новый объект. Например, если вы писали проигрыватель компакт-дисков и хотели, чтобы бит "go find info об этом компакт-диске" был настраиваемым, вместо того, чтобы делать эти методы общедоступными, вы поместили бы всю эту функциональность в свой собственный объект и сделали бы доступным только объект-получатель / установщик объекта , Таким образом, скупость в разоблачении своих внутренностей способствует хорошей композиции и разделению проблем.
Лично я придерживаюсь только «частного» и «общественного». У многих ОО-языков это есть. «Защищенный» может быть удобен, но это действительно обман. Как только интерфейс становится более приватным, он становится вне вашего контроля, и вам нужно искать код других людей, чтобы найти применение.
Вот тут-то и возникает идея «опубликованного». Изменение интерфейса (его рефакторинг) требует, чтобы вы нашли весь код, который его использует, и изменили его тоже. Если интерфейс является частным, то нет проблем. Если он защищен, вы должны найти все свои подклассы. Если это общедоступно, вы должны найти весь код, который использует ваш код. Иногда это возможно, например, если вы работаете над корпоративным кодом, предназначенным только для внутреннего использования, не имеет значения, является ли интерфейс общедоступным. Вы можете получить весь код из корпоративного хранилища. Но если интерфейс «опубликован», если есть код, использующий его вне вашего контроля, то вы попадаете в ловушку. Вы должны поддерживать этот интерфейс или рисковать нарушением кода. Даже защищенные интерфейсы можно считать опубликованными (поэтому я не
Многие языки считают иерархическую природу публичного / защищенного / частного слишком ограничивающей и не соответствующей действительности. Для этого есть концепция класса черты , но это еще одно шоу.
friends -> «Чем меньше вы знаете об этом, тем лучше» ---> Это обеспечивает избирательную видимость, которая по-прежнему превосходит конфиденциальность пакета. В C ++ он имеет свое применение, потому что не все функции могут быть функциями-членами, и друзья лучше, чем публичные публикации. Конечно, существует опасность злоупотребления злыми умами.
Себастьян Мах
30
Следует также отметить, что «защищенный» в C ++ имеет другое значение - защищенный метод является по сути закрытым, но все же может вызываться из наследующего класса. (В отличие от Java, где он может вызываться любым классом в одном и том же пакете.)
Рис ван дер Варден,
9
@RhysvanderWaerden C # - это то же самое, что и C ++ в этом аспекте. Я нахожу довольно странным, что Java не позволяет объявлять члена, который доступен подклассу, но не весь пакет. Это как бы перевернулось - пакет имеет более широкий охват, чем дочерний класс!
Конрад Моравский
15
@KonradMorawski IMHO пакет меньше, чем подкласс. Если вы не объявили свой класс финальным, пользователи должны иметь возможность подкласса его - так что Java-защита является частью вашего опубликованного интерфейса. OTOH, пакеты неявно разрабатываются одной организацией: например, com.mycompany.mypackage. Если ваш код объявляет себя в моем пакете, вы неявно объявляете себя частью моей организации, поэтому мы должны общаться. Таким образом, пакет публикуется для меньшей / легче доступной аудитории (люди в моей компании), чем для подкласса (люди, которые расширяют мой объект) и, таким образом, считается меньшей видимостью.
одноименный
2
friendхорошо для определения особых отношений между классами. Это позволяет превосходную инкапсуляцию во многих случаях при правильном использовании. Например, он может использоваться привилегированным классом фабрики для внедрения внутренних зависимостей в составной тип. У него плохое имя, потому что люди, которые не заботятся о правильном поддержании хорошо спроектированной объектной модели, могут злоупотреблять ею, чтобы облегчить свою рабочую нагрузку.
Деннис
434
Вот лучшая версия таблицы, которая также включает столбец для модулей.
Пояснения
Частный член ( i) является только доступным в том же классе , как она была объявлена.
Элемент без модификатора доступа ( j) доступен только внутри классов в одном пакете.
Защищенный член ( k) доступен во всех классах в одном пакете и в подклассах в других пакетах.
Общественный элемент ( l) доступен для всех классов (если он не находится в модуле , который не экспортировать пакет, который объявлен в).
Какой модификатор выбрать?
Модификаторы доступа - это инструмент, помогающий предотвратить случайное нарушение инкапсуляции (*) . Спросите себя, хотите ли вы, чтобы член был чем-то внутренним для класса, пакета, иерархии классов или не внутренним, и выберите соответствующий уровень доступа.
Примеры:
Поле, long internalCounterвероятно, должно быть закрытым, поскольку оно изменчиво и является деталью реализации.
Класс, который должен создаваться только в фабричном классе (в том же пакете), должен иметь конструктор с ограниченным пакетом, так как не должно быть возможности вызывать его напрямую из пакета.
Внутренний void beforeRender()метод, вызываемый непосредственно перед рендерингом и используемый как ловушка в подклассах, должен быть защищен.
void saveGame(File dst)Метод , который вызывается из кода GUI должен быть публичным.
Просто скажу: есть много людей, у которых есть проблемы с различением красного / зеленого цвета. Таблицы, использующие красные / зеленые (или желтые / оранжевые / ...) схемы окраски, редко бывают «лучше» в чем-либо ;-)
GhostCat
1
@ GhostCat, я не согласен. Я думаю , что красный / зеленый Выравнивает интуитивно с «работой» / «не работает» для многих людей, т.е. это лучше , чем у многих альтернатив.
августа
8
colourblindawareness.org/colour-blindness/… ... 8% дальтоников можно разделить примерно на 1% дейтеранопов, 1% протанопов, 1% протаномалозных и 5% дейтераномных . И так как я один из тех 50% из этих 5%, будьте уверены: красный / зеленый отстой.
GhostCat
6
@ GhostCat Хорошо ... это большая часть населения, чем я ожидал. Я загрузил изображение в этот симулятор дальтонизма и протестировал все разные режимы. Даже в режиме монохроматичности / ахроматопсии разница в цвете является разумной. Вы видите разницу или симулятор выключен? (Я по-прежнему придерживаюсь мнения, что красный / зеленый очень интуитивно понятен для людей, которые видят цвета.)
aioobe,
3
Я вижу разницу, но я также могу пройти половину тестов на дальтонизм, которые мы должны сделать в Германии для получения водительских прав ;-) ... но я думаю, что такой симулятор "достаточно хорош".
GhostCat
206
____________________________________________________________________
| 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|✔|✘|✘|✘
____________________________________________________________________
Стоит выразить словами: «Защищенный модификатор делает объект доступным для других пакетов, тогда как default / no-modifier ограничивает доступ к одному и тому же пакету»
vanguard69
2
@ vanguard69, protectedмодификатор делает помеченную вещь (класс, метод или поле) доступной для какого-то другого класса в каком-то другом пакете только в том случае, если другой класс является подклассом класса, в котором объявлена эта protectedпомеченная вещь .
Абдул
"nonsubbed"? "этот подкласс в другой упаковке"? Да. Я думал, что знаю Java.
Простое правило. Начните с объявления всего частного. И затем прогресс по отношению к публике, когда потребности возникают, и дизайн оправдывает это.
Представляя участников, спросите себя, выставляете ли вы выбор представлений или выбор абстракций. Первое - это то, чего вы хотите избежать, так как оно вводит слишком много зависимостей от реального представления, а не от его наблюдаемого поведения.
Как правило, я стараюсь избегать переопределения реализаций методов путем создания подклассов; слишком легко испортить логику. Объявите абстрактно защищенные методы, если вы собираетесь переопределить его.
Кроме того, используйте аннотацию @Override при переопределении, чтобы предотвратить поломку при рефакторинге.
@RuchirBaronia, "world" = весь код приложения, независимо от того, где он находится.
Андрейс
116
Это на самом деле немного сложнее, чем простая сетка показывает. Сетка говорит вам, разрешен ли доступ, но что именно представляет собой доступ? Кроме того, уровни доступа взаимодействуют с вложенными классами и наследованием сложным образом.
Доступ по умолчанию (определяемый отсутствием ключевого слова) также называется package-private . Исключение: в интерфейсе нет модификатора, означающего публичный доступ; запрещены модификаторы, кроме public. Константы перечисления всегда общедоступны.
Резюме
Разрешен ли доступ к участнику с этим спецификатором доступа?
Member is private: Только если member определен в том же классе, что и вызывающий код.
Участник является частным пакетом: только в том случае, если вызывающий код находится в пакете, который непосредственно входит в состав участника.
Member is protected: тот же пакет, или если member определен в суперклассе класса, содержащего вызывающий код.
Участник public: Да.
К каким спецификаторам доступа применяются
Локальные переменные и формальные параметры не могут принимать спецификаторы доступа. Поскольку они по своей природе недоступны для внешних пользователей в соответствии с правилами области видимости, они фактически являются частными.
Для классов в верхней области publicразрешены только и private-package. Такой дизайн, по- видимому , потому protectedи privateбудет излишним на уровне пакета (нет наследования пакетов).
Все спецификаторы доступа возможны для членов класса (конструкторы, методы и статические функции-члены, вложенные классы).
Спецификаторы доступа могут быть строго упорядочены
public> protected> package-private> private
Это означает, что publicобеспечивает максимальный доступ, privateнаименьший. Любая возможная ссылка на приватного участника также действительна для пакетного частного участника; любая ссылка на закрытый элемент пакета действительна для защищенного члена и т. д. (Предоставление доступа к защищенным членам другим классам в том же пакете было сочтено ошибкой.)
Вам нужен доступ к конструктору для создания объекта. Таким образом, если все конструкторы являются закрытыми, класс может быть создан только с помощью кода, живущего внутри класса (обычно это статические фабричные методы или инициализаторы статических переменных). Аналогично для частных или защищенных конструкторов.
Только наличие частных конструкторов также означает, что класс не может быть разделен на подклассы извне, поскольку Java требует, чтобы конструкторы подкласса неявно или явно вызывали конструктор суперкласса. (Однако он может содержать вложенный класс, который подклассирует его.)
Внутренние классы
Вы также должны учитывать вложенные области видимости, такие как внутренние классы. Примером сложности является то, что у внутренних классов есть члены, которые сами могут принимать модификаторы доступа. Таким образом, вы можете иметь закрытый внутренний класс с открытым членом; можно ли получить доступ к члену? (См. Ниже.) Общее правило - смотреть на область видимости и рекурсивно думать, можете ли вы получить доступ к каждому уровню.
Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interfaceExample.leakPrivateClass().secretMethod();// error^1 error
«модификаторы, отличные от public, запрещены» - с Java 9 это уже не так: интерфейсы также могут иметь закрытые методы.
MC Emperor
96
Как правило большого пальца:
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 |+—————————————————+————————————+———————————+
Самый неправильно понятый модификатор доступа в Java - это protected. Мы знаем, что он похож на модификатор по умолчанию с одним исключением, в котором его могут видеть подклассы. Но как? Вот пример, который, надеюсь, проясняет путаницу:
Предположим, что у нас есть 2 класса; Fatherи Sonкаждый в своем пакете:
package fatherpackage;publicclassFather{publicvoid fatherMethod(Father f){
f.foo();// valid even if foo() is private}}-------------------------------------------package sonpackage;publicclassSonextendsFather{publicvoid sonMethod(Son s){
s.foo();}}
Для ссылки, тип которой является родительским классом, и он находится внутри пакета, где foo()определен ( fatherpackage) [Это может быть включено в контекст №. 1]:
В чем разница между выполнением super.foo()и первой неверной ситуацией f.foo()?
cst1992
1
@ cst1992 Это сбивает с толку, но смотрите спецификацию языка Java 6.6.2: «Защищенный член или конструктор объекта может быть доступен извне пакета, в котором он объявлен только кодом, отвечающим за реализацию этого объекта». С super.foo () ссылка «super» является «непосредственно ответственной за реализацию», а ссылка «f» - нет. Почему? Потому что вы можете быть на 100% уверены, что «супер» относится к типу «Отец», но не для «f»; во время выполнения это может быть какой-то другой подтип отца. См. Docs.oracle.com/javase/specs/jls/se9/html/…
скомиса
1
Приятно читать ответ от того, кто понимает protected. К сожалению, все остальные ответы на этой странице, которые определяют protectedэто, немного ошибочны.
Дауд ибн Карим
30
Частный
Методы, переменные и конструкторы
Методы, переменные и конструкторы, которые объявлены закрытыми, могут быть доступны только внутри самого объявленного класса.
Класс и интерфейс
Модификатор частного доступа является наиболее ограниченным уровнем доступа. Класс и интерфейсы не могут быть приватными.
Запись
Переменные, которые объявлены закрытыми, могут быть доступны вне класса, если в классе присутствуют общедоступные методы получения. Переменные, методы и конструкторы, которые объявлены защищенными в суперклассе, могут быть доступны только подклассам в другом пакете или любом классе в пакете класса защищенных членов.
защищенный
Класс и интерфейс
Модификатор защищенного доступа нельзя применять к классу и интерфейсам.
Методы, поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.
Запись
Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, в то же время предотвращая попытки его использования не связанным классом.
общественного
Класс, метод, конструктор, интерфейс и т. Д., Объявленные как public, могут быть доступны из любого другого класса.
Поэтому к полям, методам, блокам, объявленным внутри открытого класса, можно получить доступ из любого класса, принадлежащего Java Universe.
Разные пакеты
Однако если публичный класс, к которому мы пытаемся получить доступ, находится в другом пакете, тогда публичный класс все равно необходимо импортировать.
Из-за наследования классов все открытые методы и переменные класса наследуются его подклассами.
По умолчанию - нет ключевого слова:
Модификатор доступа по умолчанию означает, что мы не объявляем явно модификатор доступа для класса, поля, метода и т. Д.
В рамках одного пакета
Переменная или метод, объявленные без какого-либо модификатора контроля доступа, доступны любому другому классу в том же пакете. Поля в интерфейсе неявно являются public static final, а методы в интерфейсе по умолчанию являются public.
Запись
Мы не можем переопределить статические поля. Если вы пытаетесь переопределить, это не показывает никакой ошибки, но это не работает, что мы кроме.
Разницу можно найти в уже предоставленных ссылках, но какую из них использовать обычно сводится к «Принципу наименьшего знания». Разрешить только наименьшую видимость, которая необходима.
Модификаторы доступа предназначены для ограничения доступа на нескольких уровнях.
Общественность: Это в основном так же просто, как вы можете получить доступ из любого класса, находится ли он в одном пакете или нет.
Чтобы получить доступ, если вы находитесь в том же пакете, вы можете получить доступ напрямую, но если вы находитесь в другом пакете, то вы можете создать объект класса.
По умолчанию: он доступен в одном пакете из любого класса пакета.
Для доступа вы можете создать объект класса. Но вы не можете получить доступ к этой переменной за пределами пакета.
Защищено: вы можете получить доступ к переменным в том же пакете, а также к подклассу в любом другом пакете. так что в основном это по умолчанию + унаследованное поведение.
Для доступа к защищенному полю, определенному в базовом классе, вы можете создать объект дочернего класса.
Частный: это может быть доступ в том же классе.
В нестатических методах вы можете получить доступ напрямую из-за этой ссылки (также в конструкторах), но для доступа в статических методах вам нужно создать объект класса.
Модификаторы доступа Java используются для обеспечения контроля доступа в Java.
1. По умолчанию:
Доступно только для классов в одном пакете.
Например,
// Saved in file A.javapackage pack;class A{void msg(){System.out.println("Hello");}}// Saved in file B.javapackage mypack;import pack.*;class B{publicstaticvoid main(String args[]){
A obj =new A();// Compile Time Error
obj.msg();// Compile Time Error}}
Этот доступ более ограничен, чем общедоступный и защищенный, но менее ограничен, чем частный.
2. Публичная
Может быть доступен из любого места. (Глобальный доступ)
Например,
// Saved in file A.javapackage pack;publicclass A{publicvoid msg(){System.out.println("Hello");}}// Saved in file B.javapackage mypack;import pack.*;class B{publicstaticvoid main(String args[]){
A obj =new A();
obj.msg();}}
Вывод: Привет
3. Частный
Доступно только внутри одного класса.
Если вы попытаетесь получить доступ к закрытым членам одного класса в другом, вы получите ошибку компиляции. Например,
class A{privateint data =40;privatevoid msg(){System.out.println("Hello java");}}publicclassSimple{publicstaticvoid 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.javapackage pack;publicclass A{protectedvoid msg(){System.out.println("Hello");}}// Saved in file B.javapackage mypack;import pack.*;class B extends A{publicstaticvoid main(String args[]){
B obj =new B();
obj.msg();}}
Видна на упаковке. По умолчанию. Модификаторы не нужны.
Доступно только для класса ( личное ).
Видимый миру ( публичный ).
Доступно для пакета и всех подклассов ( защищено ).
Переменные и методы могут быть объявлены без каких-либо вызываемых модификаторов. Примеры по умолчанию:
String name ="john";publicint age(){return age;}
Модификатор частного доступа - частный:
Методы, переменные и конструкторы, которые объявлены закрытыми, могут быть доступны только внутри самого объявленного класса. Модификатор частного доступа является наиболее ограниченным уровнем доступа. Класс и интерфейсы не могут быть приватными.
Переменные, которые объявлены закрытыми, могут быть доступны вне класса, если в классе присутствуют общедоступные методы получения.
Использование модификатора private - это основной способ, которым объект инкапсулирует себя и скрывает данные от внешнего мира.
Класс, метод, конструктор, интерфейс и т. Д., Объявленные как public, могут быть доступны из любого другого класса. Поэтому к полям, методам, блокам, объявленным внутри открытого класса, можно получить доступ из любого класса, принадлежащего юниверсу Java.
Однако если публичный класс, к которому мы пытаемся получить доступ, находится в другом пакете, тогда публичный класс все равно необходимо импортировать.
Из-за наследования классов все открытые методы и переменные класса наследуются его подклассами.
Пример:
publicvoid cal(){}
Модификатор защищенного доступа - protected:
Переменные, методы и конструкторы, которые объявлены защищенными в суперклассе, могут быть доступны только подклассам в другом пакете или любом классе в пакете класса защищенных членов.
Модификатор защищенного доступа нельзя применять к классу и интерфейсам. Методы, поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.
Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, в то же время предотвращая попытки его использования не связанным классом.
.... Защищенный: модификатор защищенного доступа немного сложен, и вы можете сказать, что это расширенный вариант модификатора доступа по умолчанию. Защищенные члены такие же, как и члены по умолчанию, если речь идет о доступе в том же пакете. Разница в том, что защищенные члены также доступны для подклассов класса, в котором объявлен член, которые находятся вне пакета, в котором присутствует родительский класс.
Но эти защищенные члены «доступны вне пакета только по наследству». то есть вы можете получить доступ к защищенному члену класса в его подклассе, представленном в каком-либо другом пакете, напрямую, как если бы этот член присутствовал в самом подклассе. Но этот защищенный член не будет доступен в подклассе за пределами пакета, используя ссылку родительского класса. ....
Просто добавьте это: «Как только ребенок получает доступ к защищенному члену родительского класса, он становится закрытым (точнее, я бы сказал, специальным закрытым членом, который может наследоваться подклассами подкласса) членом подкласса».
Ананд
9
Ответ Дэвида обеспечивает значение каждого модификатора доступа. Что касается того, когда использовать каждый из них, я бы предложил обнародовать все классы и методы каждого класса, предназначенные для внешнего использования (его API), а все остальное - приватно.
Со временем вы поймете, когда делать некоторые классы закрытыми для пакетов, а когда объявлять определенные методы защищенными для использования в подклассах.
Модификатор доступа 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, уровни доступа определяют, какие члены этих классов могут использовать ваши собственные классы. Во-вторых, когда вы пишете класс, вам нужно решить, какой уровень доступа должна иметь каждая переменная-член и каждый метод в вашем классе.
Что именно является дополнением, и почему это не редактирование существующего поста?
Сех
Дополнение - Модификаторы доступа. Почему бы не редактировать? Сохранить принятый ответ без изменений для исторической пользы и дать мой ответ.
ישו אוהב אותך
5
Public Protected Default и private являются модификаторами доступа.
Они предназначены для инкапсуляции или скрытия и отображения содержимого класса.
Класс может быть публичным или по умолчанию
Члены класса могут быть открытыми, защищенными, стандартными или закрытыми.
Закрытый недоступен вне класса. По умолчанию доступен только в пакете. Защищено как в пакете, так и в любом классе, который его расширяет. Общественность открыта для всех.
Обычно переменные-члены определяются как частные, но методы-члены являются открытыми.
Defaultне является модификатором доступа, а два других написаны с ошибками.
Маркиз Лорн
5
Часто я осознавал, что запоминание основных понятий любого языка стало возможным благодаря созданию реальных аналогий. Вот моя аналогия для понимания модификаторов доступа в Java:
Давайте предположим, что вы студент университета и у вас есть друг, который приедет к вам на выходные. Предположим, что в центре кампуса находится большая статуя основателя университета.
Когда вы приводите его в кампус, первое, что вы и ваш друг видите, это эта статуя. Это означает, что любой, кто ходит по кампусу, может посмотреть на статую без разрешения университета. Это делает статую как PUBLIC .
Далее вы хотите отвести вашего друга в общежитие, но для этого вам необходимо зарегистрировать его в качестве посетителя. Это означает, что он получает пропуск (такой же, как у вас), чтобы попасть в различные здания в кампусе. Это сделало бы его карту доступа ЗАЩИЩЕННОЙ .
Ваш друг хочет войти в кампус Wi-Fi, но не имеет никаких учетных данных для этого. Единственный способ, которым он может выйти в Интернет, - это если вы поделитесь с ним своим логином. (Помните, что каждый студент, который поступает в университет, также имеет эти учетные данные). Это сделало бы ваши учетные данные для входа без модификатора .
Наконец, ваш друг хочет прочитать ваш отчет о проделанной работе за семестр, который размещен на сайте. Тем не менее, у каждого студента есть свой личный логин для доступа к этому разделу сайта кампуса. Это сделало бы эти полномочия как ЧАСТНЫЕ .
Когда вы думаете о модификаторах доступа, просто подумайте об этом (относится как к переменным, так и к методам). ):
public -> доступны из любого места private -> доступный только в том же классе, где он объявлен
Теперь возникает путаница , когда речь идет defaultиprotected
default-> Ключевое слово модификатора доступа отсутствует. Это означает, что это доступно строго в пакете класса. никуда за пределами этого пакета к нему нет доступа.
protected-> Чуть менее строгие, чем defaultте же классы пакетов, но и те же классы, к которым он может получить доступ подклассами вне объявленного пакета .
Доступ Java изменяет, который вы можете использовать
Модификатор доступа может быть применим для class, field[О] , method. Попробуйте получить доступ, создать подкласс или переопределить это.
Доступ к fieldили methodчерез class.
Наследование. Преемник class(подкласс) модификатор доступа может быть любым. Преемник method(переопределить) модификатор доступа должен быть таким же или расширить его
Класс верхнего уровня (область первого уровня) может быть publicи default. Nested class[О] может иметь любой из них
Все дело в инкапсуляции (или, как сказал Джо Филлипс, минимум знаний ).
Начните с самого ограничительного (частного) и посмотрите, не понадобятся ли вам в будущем менее ограничительные модификаторы.
Мы все используем модификаторы методов и членов, такие как private, public, ... но одна вещь, которую делают немногие разработчики, - это использование пакетов для логической организации кода.
Например: вы можете поместить конфиденциальные методы защиты в пакет «security». Затем поместите открытый класс, который получает доступ к некоторому коду, связанному с безопасностью, в этом пакете, но оставьте пакет других классов безопасности закрытым . Таким образом, другие разработчики смогут использовать общедоступный класс только за пределами этого пакета (если они не изменят модификатор). Это не функция безопасности, но будет направлять использование.
Outside world ->Package(SecurityEntryClass--->Packageprivate classes)
Другое дело, что классы, которые сильно зависят друг от друга, могут оказаться в одном и том же пакете и в конечном итоге могут быть реорганизованы или объединены, если зависимость слишком сильна.
Если, наоборот, вы сделаете все общедоступным , неясно, к чему следует или не нужно обращаться, что может привести к написанию большого количества javadoc (который ничего не навязывает через компилятор ...).
@Benoit Но то, что я выложил, изображения в специальных, не одинаковы для обоих: Java и C ++? Эти правила не распространяются и на Java? спасибо
leonidaa
2
В C ++ есть только 3 модификатора, в то время как в java их 4.
Бенуа
1
аналогия хорошая, но спецификатор доступа по умолчанию отсутствует,
мс
1
OP задал вопрос "В чем разница между общедоступным, защищенным, закрытым для пакета и частным в Java?"
JL_SO
2
Мои два цента :)
частный:
класс -> класс верхнего уровня не может быть закрытым. внутренние классы могут быть приватными, которые доступны из того же класса.
переменная экземпляра -> доступна только в классе. Не может получить доступ за пределами класса.
пакет-частное:
class -> класс верхнего уровня может быть закрытым для пакета. Он может быть доступен только из одного пакета. Не из дополнительного пакета, не из внешнего пакета.
переменная экземпляра -> доступна из того же пакета. Не из дополнительного пакета, не из внешнего пакета.
защищенный:
класс -> верхнего уровня не может быть защищен.
переменная экземпляра -> Доступна только в том же пакете или подпакете. Может быть доступ только вне пакета при расширении класса.
общественности:
класс -> доступный из пакета / подпакета / другого пакета
переменная экземпляра -> доступная из пакета / подпакета / другого пакета
Если член класса объявлен с общедоступным, то к нему можно получить доступ из любого места
защищенный
Если член класса объявлен с защищенным ключевым словом, то к нему можно получить доступ из тех же членов класса, вне членов класса в том же пакете и унаследованных членов класса. Если член класса защищен, то к нему нельзя получить доступ извне класса пакета, если только внешний упакованный класс не унаследован, т.е. расширяет суперкласс другого пакета. Но защищенный член класса всегда доступен для одних и тех же классов пакетов, это НЕ имеет значения, наследуется ли один и тот же класс пакета или НЕТ
дефолт
В 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
скрывается от других классов в пакете.public
подвергает классам вне пакета.protected
версияpublic
ограничена только подклассами.protected
этот метод также доступен из всего пакета. Эта глупость в модели видимости Java нарушает цельprotected
.protected
. В качестве модификатора доступа все, чтоprotected
нужно сделать, это предоставить подклассам вне пакета.protected
- и я цитирую - «версия публичного доступа, ограниченная только подклассами», что не соответствует действительности по вашему собственному допущению, так как защищенный также разрешает доступ через весь пакет (то есть он не ограничивает доступ к подклассам. )protected-package
для тех редких случаев, когда он нам действительно нужен, оставляяprotected
эквивалент эквивалентной версии C ++ защищенной.Ответы:
Официальный учебник может быть полезным для вас.
источник
private
члены могут быть просмотрены / использованы любым классом / статическим методом в одном и том же исходном файле.MyClass
и я делаю, уAnotherClass extends MyClass
меня будет доступ ко всем защищенным и открытым методам и свойствам изнутриAnotherClass
. Если яMyClass myClass = new MyClass();
вAnotherClass
где - нибудь - скажем , конструктор - я буду иметь доступ только к публичным методам , если он находится в другом пакете. Обратите внимание, что если я это сделаю,= new MyClass() { @Override protected void protectedMethod() { //some logic } };
то я получу доступ к защищенным методам, но это то же самое, что и расширение, но вместо этого встроенное.protected
что (на самом деле это довольно сложный модификатор доступа для полного понимания - большинство людей, которые думают, что знают, что наprotected
самом деле означает, не знают ). Кроме того, как отметил Богемян, он не отвечает на вопрос - он ничего не говорит о том, когда использовать каждый модификатор доступа. По моему мнению, этот ответ не достаточно плох, чтобы понизить, но близко. Но более 4000 голосов? Как это случилось?(Предостережение: я не программист на Java, я программист на Perl. У Perl нет формальной защиты, поэтому, возможно, поэтому я так хорошо понимаю проблему :))
Частный
Как вы думаете, только класс, в котором он объявлен, может видеть его.
Пакет Приват
Его может видеть и использовать только тот пакет, в котором он был объявлен. Это значение по умолчанию в Java (что некоторые считают ошибкой).
защищенный
Пакет Private + может просматриваться подклассами или членами пакета.
общественного
Каждый может это увидеть.
опубликованный
Видимо за пределами кода, который я контролирую. (Хотя это не синтаксис Java, это важно для этого обсуждения).
C ++ определяет дополнительный уровень, называемый «друг», и чем меньше вы знаете об этом, тем лучше.
Когда вы должны использовать что? Вся идея заключается в инкапсуляции, чтобы скрыть информацию. Как можно больше вы хотите скрыть детали того, как что-то делается от ваших пользователей. Почему? Потому что тогда вы можете изменить их позже и не нарушать чей-либо код. Это позволяет оптимизировать, реорганизовывать, перепроектировать и исправлять ошибки, не беспокоясь о том, что кто-то использовал этот код, который вы только что пересмотрели.
Таким образом, эмпирическое правило состоит в том, чтобы делать вещи только такими видимыми, какими они должны быть. Начните с частного и добавьте больше видимости по мере необходимости. Обнародуйте только то, что абсолютно необходимо знать пользователю, каждая деталь, которую вы публикуете, ограничивает вашу способность перепроектировать систему.
Если вы хотите, чтобы пользователи могли настраивать поведение, а не публиковать внутренние данные, чтобы они могли их переопределить, часто лучше вставить эти внутренности в объект и сделать этот интерфейс общедоступным. Таким образом, они могут просто подключить новый объект. Например, если вы писали проигрыватель компакт-дисков и хотели, чтобы бит "go find info об этом компакт-диске" был настраиваемым, вместо того, чтобы делать эти методы общедоступными, вы поместили бы всю эту функциональность в свой собственный объект и сделали бы доступным только объект-получатель / установщик объекта , Таким образом, скупость в разоблачении своих внутренностей способствует хорошей композиции и разделению проблем.
Лично я придерживаюсь только «частного» и «общественного». У многих ОО-языков это есть. «Защищенный» может быть удобен, но это действительно обман. Как только интерфейс становится более приватным, он становится вне вашего контроля, и вам нужно искать код других людей, чтобы найти применение.
Вот тут-то и возникает идея «опубликованного». Изменение интерфейса (его рефакторинг) требует, чтобы вы нашли весь код, который его использует, и изменили его тоже. Если интерфейс является частным, то нет проблем. Если он защищен, вы должны найти все свои подклассы. Если это общедоступно, вы должны найти весь код, который использует ваш код. Иногда это возможно, например, если вы работаете над корпоративным кодом, предназначенным только для внутреннего использования, не имеет значения, является ли интерфейс общедоступным. Вы можете получить весь код из корпоративного хранилища. Но если интерфейс «опубликован», если есть код, использующий его вне вашего контроля, то вы попадаете в ловушку. Вы должны поддерживать этот интерфейс или рисковать нарушением кода. Даже защищенные интерфейсы можно считать опубликованными (поэтому я не
Многие языки считают иерархическую природу публичного / защищенного / частного слишком ограничивающей и не соответствующей действительности. Для этого есть концепция класса черты , но это еще одно шоу.
источник
friend
хорошо для определения особых отношений между классами. Это позволяет превосходную инкапсуляцию во многих случаях при правильном использовании. Например, он может использоваться привилегированным классом фабрики для внедрения внутренних зависимостей в составной тип. У него плохое имя, потому что люди, которые не заботятся о правильном поддержании хорошо спроектированной объектной модели, могут злоупотреблять ею, чтобы облегчить свою рабочую нагрузку.Вот лучшая версия таблицы, которая также включает столбец для модулей.
Пояснения
Частный член (
i
) является только доступным в том же классе , как она была объявлена.Элемент без модификатора доступа (
j
) доступен только внутри классов в одном пакете.Защищенный член (
k
) доступен во всех классах в одном пакете и в подклассах в других пакетах.Общественный элемент (
l
) доступен для всех классов (если он не находится в модуле , который не экспортировать пакет, который объявлен в).Какой модификатор выбрать?
Модификаторы доступа - это инструмент, помогающий предотвратить случайное нарушение инкапсуляции (*) . Спросите себя, хотите ли вы, чтобы член был чем-то внутренним для класса, пакета, иерархии классов или не внутренним, и выберите соответствующий уровень доступа.
Примеры:
long internalCounter
вероятно, должно быть закрытым, поскольку оно изменчиво и является деталью реализации.void beforeRender()
метод, вызываемый непосредственно перед рендерингом и используемый как ловушка в подклассах, должен быть защищен.void saveGame(File dst)
Метод , который вызывается из кода GUI должен быть публичным.(*) Что такое инкапсуляция?
источник
источник
protected
модификатор делает помеченную вещь (класс, метод или поле) доступной для какого-то другого класса в каком-то другом пакете только в том случае, если другой класс является подклассом класса, в котором объявлена этаprotected
помеченная вещь .Простое правило. Начните с объявления всего частного. И затем прогресс по отношению к публике, когда потребности возникают, и дизайн оправдывает это.
Представляя участников, спросите себя, выставляете ли вы выбор представлений или выбор абстракций. Первое - это то, чего вы хотите избежать, так как оно вводит слишком много зависимостей от реального представления, а не от его наблюдаемого поведения.
Как правило, я стараюсь избегать переопределения реализаций методов путем создания подклассов; слишком легко испортить логику. Объявите абстрактно защищенные методы, если вы собираетесь переопределить его.
Кроме того, используйте аннотацию @Override при переопределении, чтобы предотвратить поломку при рефакторинге.
источник
Это на самом деле немного сложнее, чем простая сетка показывает. Сетка говорит вам, разрешен ли доступ, но что именно представляет собой доступ? Кроме того, уровни доступа взаимодействуют с вложенными классами и наследованием сложным образом.
Доступ по умолчанию (определяемый отсутствием ключевого слова) также называется package-private . Исключение: в интерфейсе нет модификатора, означающего публичный доступ; запрещены модификаторы, кроме public. Константы перечисления всегда общедоступны.
Резюме
Разрешен ли доступ к участнику с этим спецификатором доступа?
private
: Только если member определен в том же классе, что и вызывающий код.protected
: тот же пакет, или если member определен в суперклассе класса, содержащего вызывающий код.public
: Да.К каким спецификаторам доступа применяются
Локальные переменные и формальные параметры не могут принимать спецификаторы доступа. Поскольку они по своей природе недоступны для внешних пользователей в соответствии с правилами области видимости, они фактически являются частными.
Для классов в верхней области
public
разрешены только и private-package. Такой дизайн, по- видимому , потомуprotected
иprivate
будет излишним на уровне пакета (нет наследования пакетов).Все спецификаторы доступа возможны для членов класса (конструкторы, методы и статические функции-члены, вложенные классы).
Связанный: Доступность Класса Java
порядок
Спецификаторы доступа могут быть строго упорядочены
Это означает, что
public
обеспечивает максимальный доступ,private
наименьший. Любая возможная ссылка на приватного участника также действительна для пакетного частного участника; любая ссылка на закрытый элемент пакета действительна для защищенного члена и т. д. (Предоставление доступа к защищенным членам другим классам в том же пакете было сочтено ошибкой.)Ноты
private[this]
.)Внутренние классы
Вы также должны учитывать вложенные области видимости, такие как внутренние классы. Примером сложности является то, что у внутренних классов есть члены, которые сами могут принимать модификаторы доступа. Таким образом, вы можете иметь закрытый внутренний класс с открытым членом; можно ли получить доступ к члену? (См. Ниже.) Общее правило - смотреть на область видимости и рекурсивно думать, можете ли вы получить доступ к каждому уровню.
Тем не менее, это довольно сложно, и для полной информации, обратитесь к Спецификации языка Java . (Да, в прошлом были ошибки компилятора.)
Чтобы почувствовать, как они взаимодействуют, рассмотрим этот пример. Возможно «утечка» частных внутренних классов; обычно это предупреждение:
Выход компилятора:
Некоторые связанные вопросы:
источник
Как правило большого пальца:
private
: область видимостиdefault
(илиpackage-private
): объем пакета.protected
:package scope + child
(вроде пакета, но мы можем сделать его подклассом из разных пакетов). Защищенный модификатор всегда сохраняет отношения «родитель-потомок».public
: где угодно.В результате, если мы разделим право доступа на три права:
тогда у нас есть эта простая таблица:
источник
Очень коротко
public
: доступно везде.protected
: доступно классам одного пакета и подклассам, находящимся в любом пакете.private
: доступно только в одном классе.источник
Самый неправильно понятый модификатор доступа в Java - это
protected
. Мы знаем, что он похож на модификатор по умолчанию с одним исключением, в котором его могут видеть подклассы. Но как? Вот пример, который, надеюсь, проясняет путаницу:Предположим, что у нас есть 2 класса;
Father
иSon
каждый в своем пакете:Давайте добавим защищенный метод
foo()
кFather
.Метод
foo()
может быть вызван в 4 контекстах:Внутри класса, который находится в том же пакете, где
foo()
определен (fatherpackage
):Внутри подкласса, в текущем экземпляре через
this
илиsuper
:По ссылке, тип которой совпадает с классом:
Для ссылки, тип которой является родительским классом, и он находится внутри пакета, где
foo()
определен (fatherpackage
) [Это может быть включено в контекст №. 1]:Следующие ситуации недопустимы.
Для ссылки, тип которой является родительским классом, и он находится вне пакета, где
foo()
определен (fatherpackage
):Неподкласс внутри пакета подкласса (подкласс наследует защищенные члены от своего родителя и делает их закрытыми для неподклассов):
источник
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
источник
Разницу можно найти в уже предоставленных ссылках, но какую из них использовать обычно сводится к «Принципу наименьшего знания». Разрешить только наименьшую видимость, которая необходима.
источник
Частный : ограниченный доступ только к классу
По умолчанию (без модификатора) : ограниченный доступ к классу и пакету
Защищено : ограниченный доступ к классу, пакету и подклассам (как внутри, так и снаружи пакета)
Общедоступный : Доступен для класса, пакета (всех) и подклассов ... Короче говоря, везде.
источник
Модификаторы доступа предназначены для ограничения доступа на нескольких уровнях.
Общественность: Это в основном так же просто, как вы можете получить доступ из любого класса, находится ли он в одном пакете или нет.
Чтобы получить доступ, если вы находитесь в том же пакете, вы можете получить доступ напрямую, но если вы находитесь в другом пакете, то вы можете создать объект класса.
По умолчанию: он доступен в одном пакете из любого класса пакета.
Для доступа вы можете создать объект класса. Но вы не можете получить доступ к этой переменной за пределами пакета.
Защищено: вы можете получить доступ к переменным в том же пакете, а также к подклассу в любом другом пакете. так что в основном это по умолчанию + унаследованное поведение.
Для доступа к защищенному полю, определенному в базовом классе, вы можете создать объект дочернего класса.
Частный: это может быть доступ в том же классе.
В нестатических методах вы можете получить доступ напрямую из-за этой ссылки (также в конструкторах), но для доступа в статических методах вам нужно создать объект класса.
источник
Модификаторы доступа в Java.
Модификаторы доступа Java используются для обеспечения контроля доступа в Java.
1. По умолчанию:
Доступно только для классов в одном пакете.
Например,
Этот доступ более ограничен, чем общедоступный и защищенный, но менее ограничен, чем частный.
2. Публичная
Может быть доступен из любого места. (Глобальный доступ)
Например,
3. Частный
Доступно только внутри одного класса.
Если вы попытаетесь получить доступ к закрытым членам одного класса в другом, вы получите ошибку компиляции. Например,
4. Защищенный
Доступно только для классов в одном пакете и для подклассов
Например,
источник
общедоступный - доступен из любой точки приложения.
по умолчанию - доступно из пакета.
защищенный - доступный из пакета и подклассов в другом пакете. также
частный - доступен только для своего класса.
источник
Видна на упаковке. По умолчанию. Модификаторы не нужны.
Доступно только для класса ( личное ).
Видимый миру ( публичный ).
Доступно для пакета и всех подклассов ( защищено ).
Переменные и методы могут быть объявлены без каких-либо вызываемых модификаторов. Примеры по умолчанию:
Модификатор частного доступа - частный:
Методы, переменные и конструкторы, которые объявлены закрытыми, могут быть доступны только внутри самого объявленного класса. Модификатор частного доступа является наиболее ограниченным уровнем доступа. Класс и интерфейсы не могут быть приватными.
Переменные, которые объявлены закрытыми, могут быть доступны вне класса, если в классе присутствуют общедоступные методы получения.
Использование модификатора private - это основной способ, которым объект инкапсулирует себя и скрывает данные от внешнего мира.
Примеры:
Модификатор публичного доступа - публичный:
Класс, метод, конструктор, интерфейс и т. Д., Объявленные как public, могут быть доступны из любого другого класса. Поэтому к полям, методам, блокам, объявленным внутри открытого класса, можно получить доступ из любого класса, принадлежащего юниверсу Java.
Однако если публичный класс, к которому мы пытаемся получить доступ, находится в другом пакете, тогда публичный класс все равно необходимо импортировать.
Из-за наследования классов все открытые методы и переменные класса наследуются его подклассами.
Пример:
Модификатор защищенного доступа - protected:
Переменные, методы и конструкторы, которые объявлены защищенными в суперклассе, могут быть доступны только подклассам в другом пакете или любом классе в пакете класса защищенных членов.
Модификатор защищенного доступа нельзя применять к классу и интерфейсам. Методы, поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.
Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, в то же время предотвращая попытки его использования не связанным классом.
источник
Эта страница хорошо описывает модификатор защищенного доступа и доступа по умолчанию
.... Защищенный: модификатор защищенного доступа немного сложен, и вы можете сказать, что это расширенный вариант модификатора доступа по умолчанию. Защищенные члены такие же, как и члены по умолчанию, если речь идет о доступе в том же пакете. Разница в том, что защищенные члены также доступны для подклассов класса, в котором объявлен член, которые находятся вне пакета, в котором присутствует родительский класс.
Но эти защищенные члены «доступны вне пакета только по наследству». то есть вы можете получить доступ к защищенному члену класса в его подклассе, представленном в каком-либо другом пакете, напрямую, как если бы этот член присутствовал в самом подклассе. Но этот защищенный член не будет доступен в подклассе за пределами пакета, используя ссылку родительского класса. ....
источник
Ответ Дэвида обеспечивает значение каждого модификатора доступа. Что касается того, когда использовать каждый из них, я бы предложил обнародовать все классы и методы каждого класса, предназначенные для внешнего использования (его API), а все остальное - приватно.
Со временем вы поймете, когда делать некоторые классы закрытыми для пакетов, а когда объявлять определенные методы защищенными для использования в подклассах.
источник
Примечание: это всего лишь дополнение к принятому ответу.
Это связано с модификаторами доступа Java .
Из модификаторов доступа Java :
Из управления доступом к членам класса учебники:
источник
Public Protected Default и private являются модификаторами доступа.
Они предназначены для инкапсуляции или скрытия и отображения содержимого класса.
Закрытый недоступен вне класса. По умолчанию доступен только в пакете. Защищено как в пакете, так и в любом классе, который его расширяет. Общественность открыта для всех.
Обычно переменные-члены определяются как частные, но методы-члены являются открытыми.
источник
Default
не является модификатором доступа, а два других написаны с ошибками.Часто я осознавал, что запоминание основных понятий любого языка стало возможным благодаря созданию реальных аналогий. Вот моя аналогия для понимания модификаторов доступа в Java:
Давайте предположим, что вы студент университета и у вас есть друг, который приедет к вам на выходные. Предположим, что в центре кампуса находится большая статуя основателя университета.
Когда вы приводите его в кампус, первое, что вы и ваш друг видите, это эта статуя. Это означает, что любой, кто ходит по кампусу, может посмотреть на статую без разрешения университета. Это делает статую как PUBLIC .
Далее вы хотите отвести вашего друга в общежитие, но для этого вам необходимо зарегистрировать его в качестве посетителя. Это означает, что он получает пропуск (такой же, как у вас), чтобы попасть в различные здания в кампусе. Это сделало бы его карту доступа ЗАЩИЩЕННОЙ .
Ваш друг хочет войти в кампус Wi-Fi, но не имеет никаких учетных данных для этого. Единственный способ, которым он может выйти в Интернет, - это если вы поделитесь с ним своим логином. (Помните, что каждый студент, который поступает в университет, также имеет эти учетные данные). Это сделало бы ваши учетные данные для входа без модификатора .
Наконец, ваш друг хочет прочитать ваш отчет о проделанной работе за семестр, который размещен на сайте. Тем не менее, у каждого студента есть свой личный логин для доступа к этому разделу сайта кампуса. Это сделало бы эти полномочия как ЧАСТНЫЕ .
Надеюсь это поможет!
источник
Когда вы думаете о модификаторах доступа, просто подумайте об этом (относится как к переменным, так и к методам). ):
public
-> доступны из любого местаprivate
-> доступный только в том же классе, где он объявленТеперь возникает путаница , когда речь идет
default
иprotected
default
-> Ключевое слово модификатора доступа отсутствует. Это означает, что это доступно строго в пакете класса. никуда за пределами этого пакета к нему нет доступа.protected
-> Чуть менее строгие, чемdefault
те же классы пакетов, но и те же классы, к которым он может получить доступ подклассами вне объявленного пакета .источник
Доступ Java изменяет, который вы можете использовать
Модификатор доступа может быть применим для
class
,field
[О] ,method
. Попробуйте получить доступ, создать подкласс или переопределить это.field
илиmethod
черезclass
.class
(подкласс) модификатор доступа может быть любым. Преемникmethod
(переопределить) модификатор доступа должен быть таким же или расширить егоКласс верхнего уровня (область первого уровня) может быть
public
иdefault
.Nested class
[О] может иметь любой из нихpackage
не относится к иерархии пакетовБыстрые модификаторы доступа
источник
Все дело в инкапсуляции (или, как сказал Джо Филлипс, минимум знаний ).
Начните с самого ограничительного (частного) и посмотрите, не понадобятся ли вам в будущем менее ограничительные модификаторы.
Мы все используем модификаторы методов и членов, такие как private, public, ... но одна вещь, которую делают немногие разработчики, - это использование пакетов для логической организации кода.
Например: вы можете поместить конфиденциальные методы защиты в пакет «security». Затем поместите открытый класс, который получает доступ к некоторому коду, связанному с безопасностью, в этом пакете, но оставьте пакет других классов безопасности закрытым . Таким образом, другие разработчики смогут использовать общедоступный класс только за пределами этого пакета (если они не изменят модификатор). Это не функция безопасности, но будет направлять использование.
Другое дело, что классы, которые сильно зависят друг от друга, могут оказаться в одном и том же пакете и в конечном итоге могут быть реорганизованы или объединены, если зависимость слишком сильна.
Если, наоборот, вы сделаете все общедоступным , неясно, к чему следует или не нужно обращаться, что может привести к написанию большого количества javadoc (который ничего не навязывает через компилятор ...).
источник
После блок - схема объясняет , как данные члены базового класса являются унаследовали , когда производный класс режим доступа частных .
Примечание. Объявление членов данных с помощью частного спецификатора доступа называется скрытием данных.
Источник: Спецификаторы доступа - частный, публичный и защищенный
источник
Мои два цента :)
частный:
класс -> класс верхнего уровня не может быть закрытым. внутренние классы могут быть приватными, которые доступны из того же класса.
переменная экземпляра -> доступна только в классе. Не может получить доступ за пределами класса.
пакет-частное:
class -> класс верхнего уровня может быть закрытым для пакета. Он может быть доступен только из одного пакета. Не из дополнительного пакета, не из внешнего пакета.
переменная экземпляра -> доступна из того же пакета. Не из дополнительного пакета, не из внешнего пакета.
защищенный:
класс -> верхнего уровня не может быть защищен.
переменная экземпляра -> Доступна только в том же пакете или подпакете. Может быть доступ только вне пакета при расширении класса.
общественности:
класс -> доступный из пакета / подпакета / другого пакета
переменная экземпляра -> доступная из пакета / подпакета / другого пакета
Вот подробный ответ
https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md
источник
общественности
Если член класса объявлен с общедоступным, то к нему можно получить доступ из любого места
защищенный
Если член класса объявлен с защищенным ключевым словом, то к нему можно получить доступ из тех же членов класса, вне членов класса в том же пакете и унаследованных членов класса. Если член класса защищен, то к нему нельзя получить доступ извне класса пакета, если только внешний упакованный класс не унаследован, т.е. расширяет суперкласс другого пакета. Но защищенный член класса всегда доступен для одних и тех же классов пакетов, это НЕ имеет значения, наследуется ли один и тот же класс пакета или НЕТ
дефолт
В Java по умолчанию НЕ используется ключевое слово модификатора доступа. Если член класса объявлен без ключевого слова модификатора доступа, то в этом случае он считается членом по умолчанию. Член класса по умолчанию всегда доступен тем же членам класса пакета. Но внешний член класса пакета НЕ может получить доступ к членам класса по умолчанию, даже если внешние классы являются подклассами в отличие от защищенных членов.
частный
Если член класса объявлен с ключевым словом защищен, то в этом случае он доступен ТОЛЬКО для тех же членов класса
источник
Спецификаторы доступа в Java: в java есть 4 спецификатора доступа: приватный, приватный (по умолчанию), защищенный и публичный в порядке возрастания доступа.
Приватный : Когда вы разрабатываете какой-то класс и хотите, чтобы член этого класса не был представлен вне этого класса, вы должны объявить его как закрытый. частные члены могут быть доступны только в классе, где они определены, т.е. в классе. Закрытые члены могут быть доступны по ссылке «this», а также по другим экземплярам класса, содержащим эти члены, но только в пределах определения этого класса.
Частный пакет (по умолчанию) : этот спецификатор доступа предоставит доступ, указанный спецификатором частного доступа, в дополнение к описанному ниже доступу.
Когда вы разрабатываете какой-то пакет и, следовательно, какой-то класс (скажем, Class1) внутри него, вы можете использовать спецификатор доступа по умолчанию (не нужно упоминать явно), чтобы выставить член внутри класса, другим классам в вашем (том же) пакете. В этих других классах (в том же пакете) вы можете получить доступ к этим элементам по умолчанию в экземпляре Class1. Также вы можете получить доступ к этим элементам по умолчанию в подклассах Class1, скажем Class2 (по этой ссылке или в экземпляре Class1 или в экземпляре Class2).
По сути, в одном и том же пакете вы можете получить доступ к членам по умолчанию в экземпляре класса напрямую или по ссылке this в подклассах.
защищенный : этот спецификатор доступа будет предоставлять доступ, указанный в спецификаторе частного доступа к пакету, в дополнение к описанному ниже доступу.
Когда вы разрабатываете некоторый пакет и, следовательно, некоторый класс (скажем, Class1) внутри него, вам следует использовать спецификатор защищенного доступа для члена данных в Class1, если вы не хотите, чтобы этот член был доступен вне вашего пакета (скажем, в пакете потребителя ваш пакет, т.е. клиент, который использует ваши API) в целом, но вы хотите сделать исключение и разрешить доступ к этому члену, только если клиент пишет класс, скажем, Class2, который расширяет Class1. Таким образом, в общем случае защищенные члены будут доступны по ссылке «this» в производных классах, т.е. Class2, а также в явных экземплярах Class2.
Пожалуйста, обратите внимание:
Таким образом, суть в том, что к защищенным членам можно получить доступ в других пакетах, только если некоторый класс из этого другого пакета расширяет класс, включающий этот защищенный член, и защищенный член доступен по ссылке «this» или явным экземплярам расширенного класса, в пределах определения расширенного учебный класс.
public : этот спецификатор доступа предоставит доступ, указанный спецификатором защищенного доступа, в дополнение к описанному ниже доступу.
Когда вы разрабатываете некоторый пакет и, следовательно, некоторый класс (скажем, Class1) внутри него, вам следует использовать общедоступный спецификатор для члена данных в Class1, если вы хотите, чтобы этот член был доступен в других пакетах на экземпляре Class1, созданном в каком-то другом классе. пакет. По сути, этот спецификатор доступа следует использовать, когда вы намереваетесь представить свой элемент данных миру без каких-либо условий.
источник