Модификаторы private, protected, public в Java
Модификаторы доступа private, protected, public ставятся перед именем класса, метода или поля и ограничивают доступ к нему. К локальным переменным модификаторы доступа не применимы.
Помимо этих трех явных модификаторов, есть еще так называемый default-модификатор, или модификатор по умолчанию, иначе говоря — это отсутствие всякого модификатора. Но это отсутствие тоже подразумевает свои правила доступа (видимость только внутри пакета).
Зачем нужны модификаторы доступа
Модификаторы доступа существуют для того, чтобы сделать код надежнее и защищеннее. Нужно максимально ограничивать видимость своих классов, методов и полей, и открывать их только там, где это действительно необходимо. Если вы откроете что-то лишнее, то другой разработчик (или даже вы сами) может по ошибке воспользоваться открытым классом/методом. Чем это чревато? А тем, что если в дальнейшем вы исправите свой код (отвечающий за внутреннюю реализацию, но открытый для пользования извне), то код другого программиста перестанет работать, так как опирается на ваш код. Открывать нужно только то, что вы планируете поддерживать и что будет стабильно работать (без изменения контракта) во всех последующих версиях. Все остальное — внутренняя реализация, которая касается только вас и может меняться, ее никто не должен использовать.
Правила доступа
На картинке показаны правила доступа к полю или методу с конкретным модификатором (последний столбец — про модули, они появились в Java 9):

Модификатор private
Это самый ограничивающий модификатор. К полям и методам, помеченным ключевым словом private, можно обратиться только из того же класса, где они находятся.
Допустим у нас есть класс A с private полем privateVar и с private методом privateMethod(). Из класса A мы можем обращаться к полю, см. обращение this.privateVar:
А теперь попробуем обратиться к этому полю и методу из класса B, код не скомпилируется:
Вышеприведенный код выдает ошибки компиляции:
Иногда возникает вопрос
Может ли объект A получить доступ к private методам и полям другого объекта A?
Да, может. Обратите внимание на функцию main() из вышеприведенного класса A, в которой создается новый объект A и идет обращение к его методам и полям (не через this):
Как показано выше, мы обращаемся в методе main() к private полю privateVar другого объекта A, и это законно. Все потому, что в Java ограничения доступа применимы на уровне класса, а не на уровне объекта (не обязательно, чтоб обращение шло к тому же экземпляру, главное, что он в том же классе).
Можно ли переопределить private метод?
Нельзя, метод в подклассе не будет иметь никакого отношения к методу в суперклассе, так как private метод нигде не виден. Давайте попытаемся унаследоваться от класса A и «переопределить» private метод privateMethod():
Попробуем создать объект SubA и вызвать privateMethod() на A:
Как видите, срабатывает метод privateMethod() класса A, то есть переопределения не происходит:
Это происходит потому, что метод privateMethod() класса SubA не переопределяет метод privateMethod() класса A, а является независимым методом.
Модификатор default
Если мы не ставим никакого модификатора доступа перед методом, полем или классом, то этот метод/поле/класс видимы из кода только внутри пакета, в котором они находятся.
Давайте продемонстрируем это. Создадим снова класс A в пакете .def:
И создадим в этом же пакете класс B, из которого будем пытаться получить доступ к полям и методам A, как и раньше:
В этот раз код компилируется, все в порядке — доступ есть.
Если бы класс B находится в другом пакете (отличном от ru.sysout.accessmodifiers.def, в том числе в подпакете), то доступа бы не было.
Модификатор protected
Следующий по строгости — модификатор protected. Он также разрешает доступ к помеченным с помощью него полям и методам из кода внутри того же пакета. Но помимо этого, он дает поблажки подклассам, находящимся в другом пакете. Подкласс может обращаться к protected полям и методам суперкласса, даже если подкласс находится в другом пакете.
Снова создадим класс A с protected полем и методом:
Создадим в другом пакете класс C — наследника класса A и попытаемся получить доступ к полям методам класса A из класса C:
Как показано выше, обращение к полю и методу через this работает из другого пакета.
Также работает обращение ко всем другим экземплярам типа C, но к другим экземплярам типа A обращение не работает.
Модификатор public
Тут все просто — к полю и методу с модификатором public имеет доступ любой код. Давайте еще раз перепишем класс A:
И обратимся к его полю и методу из класса B, который находится в другом пакете и никакого отношения к классу A не имеет:
Все получилось, обращение работает.
Какой модификатор выбрать?
Правило выбора модификатора такое — надо по возможности выбирать:
То есть надо максимально ограничивать видимость члена класса. Сначала надо попробовать сделать все private, и при необходимости открывать видимость.
Мы рассмотрели тонкости использования модификаторов доступа. Код примеров можно посмотреть на GitHub.
Какие модификаторы доступа существуют в Java?
Модификаторы доступа определяет, какие классы могут обращаться к данному классу и его полям, конструкторам и методам. Могут быть указаны отдельно для класса, его конструкторов, полей и методов и иметь один из четырех различных модификаторов:
Следующая таблица суммирует, к каким конструкциям Java может применяться каждый модификатор:
| private | default | protected | public | |
|---|---|---|---|---|
| Класс | No | Yes | No | Yes |
| Вложенный класс | Yes | Yes | Yes | Yes |
| Конструктор | Yes | Yes | Yes | Yes |
| Метод | Yes | Yes | Yes | Yes |
| Поля | Yes | Yes | Yes | Yes |
Private
Если метод или переменная помечены как private (им назначен модификатор частного доступа), то только код внутри того же класса может получить доступ к переменной или вызвать метод. Код внутри подклассов не может получить доступ к переменной или методу, равно как и код из любого внешнего класса.
Классы не могут быть помечены таким модификатором. Подобная пометка класса будет означать, что никакой другой класс не сможет получить к нему доступ, а это означает, что вы вообще не сможете использовать его.
Вот пример назначения к полю:
Переменная – long time была помечена как частная. Это означает, что переменная long time внутри класса Clock недоступна из кода вне него.
Доступ к частным полям
Поля часто объявляются частными для контроля доступа к ним из внешнего мира. В некоторых случаях поля являются действительно закрытыми, то есть они используются только внутри класса. В других случаях к полям можно получить доступ через методы доступа (например, геттеры и сеттеры). Вот пример:
В приведенном выше примере два метода getTime() и setTime() могут получить доступ к переменной long time. Два метода объявлены как публичные, то есть они могут быть вызваны из кода в любом месте вашего приложения.
Частные конструкторы
Если конструктору в классе назначен частный модификатор, это означает, что конструктор не может быть вызван из-за пределов класса. Закрытый конструктор все еще может вызываться из других конструкторов или из статических методов того же класса:
Эта версия класса Clock содержит приватный конструктор и публичный конструктор. Закрытый конструктор вызывается из публичного (оператор this();). Он также вызывается из статического метода newClock().
Приведенный выше пример служит только для того, чтобы показать вам, что закрытый конструктор можно вызывать из открытых и из статических методов внутри одного и того же класса.
Default
Объявляется без записи модификатора доступа вообще. Означает, что код внутри самого класса, а также код внутри классов в том же пакете, что и этот класс, могут обращаться к классу, полю, конструктору или методу, которому назначен такой модификатор. Поэтому эту разновидность также иногда называют модификатором доступа к пакету.
Подклассы не могут получить доступ к методам и переменным-членам (полям) в суперклассе, если эти методы и поля помечены этим модификатором, если только подкласс не находится в том же пакете, что и суперкласс.
Поле времени в классе Clock не имеет модификатора, что означает, что ему неявно назначен по умолчанию. Следовательно, класс ClockReader может считывать переменную-член time объекта Clock при условии, что ClockReader и Clock находятся в одном и том же пакете Java.
Protected
Обеспечивает тот же доступ, что и модификатор по умолчанию, кроме того, подклассы могут обращаться к защищенным методам и переменным (полям) членов суперкласса. Это верно, даже если подкласс не находится в том же пакете, что и суперкласс.
В вышеприведенном примере у подкласса SmartClock есть метод getTimeInSeconds(), который обращается к переменной времени Clock суперкласса. Это возможно, даже если Clock и SmartClock не находятся в одном и том же пакете, поскольку поле времени помечено соответствующим модификатором.
Public
Общедоступный модификатор означает, что весь код может получить доступ к классу, полю, конструктору или методу независимо от того, где находится код доступа (в другом классе и в другом пакете):
Поле времени в классе Clock помечено общедоступным модификатором. Поэтому класс ClockReader может обращаться к полю времени в Clock независимо от того, в каком пакете находится ClockReader.
Доступ к классу
Важно помнить, что модификатор, назначенный классу, имеет приоритет над любыми модификаторами, назначенными полям, конструкторам и методам этого класса. Если класс помечен модификатором по умолчанию, то никакой другой класс вне того же пакета не может получить доступ к этому классу, включая его конструкторы, поля и методы. Это не поможет, если вы объявите эти поля общедоступными.
Частные и защищенные модификаторы не могут быть назначены классу. Только для конструкторов, методов и полей внутри классов. Классам могут быть назначены только по умолчанию (пакет) и общедоступный.
К интерфейсу
Java-интерфейсы предназначены для указания общедоступных полей и методов в классах, которые они реализуют. Поэтому вы не можете использовать модификаторы частного и защищенного доступа в них. Поля и методы в интерфейсах неявно объявляются общедоступными, если вы пропустите модификатор, поэтому вы также не можете использовать модификатор по умолчанию (без него).
Модификаторы и наследование
Когда вы создаете подкласс некоторого класса, у методов в подклассе не может быть назначено им менее доступных модификаторов, чем в суперклассе.
Например, если метод в суперклассе является общедоступным, то он также должен быть таким в подклассе, в случае, если подкласс переопределяет метод. Если метод в суперклассе защищен, то он должен быть защищенным или общедоступным в подклассе.
Хотя не разрешено уменьшать доступность переопределенного метода, разрешено расширять доступность переопределенного метода. Например, если методу назначен модификатор по умолчанию в суперклассе, то разрешается назначать переопределенный метод в подклассе модификатору открытого доступа.
8. Java — Модификаторы доступа и класса
Модификаторы — ключевые слова, которые Вы добавляете при инициализации для изменения значений. Язык Java имеет широкий спектр модификаторов, основные из них:
Чтобы использовать модификатор в Java, нужно включить его ключевое слово в определение класса, метода или переменной. Модификатор должен быть впереди остальной части оператора, как показано в следующих примерах:
Содержание
Модификаторы доступа
Java предоставляет ряд модификаторов доступа, чтобы задать уровни доступа для классов, переменных, методов и конструкторов. Существует четыре доступа:
Модификатор доступа по умолчанию — без ключевого слова
Модификатор доступа по умолчанию — означает, что мы явно не объявляем модификатор доступа в Java для класса, поля, метода и т.д.
Переменная или метод, объявленные без модификатора контроля доступа доступны для любого другого класса в том же пакете. Поля в интерфейсе неявно являются public, static, final, а методы в интерфейсе по умолчанию являются public.
Пример
Переменные и методы могут быть объявлены в Java без каких-либо модификаторов, как показано в следующем примере:
Модификатор доступа private
Модификатор private — методы, переменные и конструкторы, которые объявлены как private в Java могут быть доступны только в пределах самого объявленного класса.
Модификатор доступа private является наиболее ограничивающим уровенем доступа. Класс и интерфейсы не могут быть private.
Переменные, объявленные как private, могут быть доступны вне класса, если получающие их открытые (public) методы присутствуют в классе (ниже смотрите пример и пояснения).
Использование модификатора private в Java является основным способом, чтобы скрыть данные.
Пример
Следующий класс использует контроль доступа private:
Здесь переменная format класса Logger является private, так что нет никакого способа для других классов, чтобы получить и установить её значение напрямую.
Таким образом, чтобы эта переменная была доступна для всего, мы определили два открытых (public) метода: getFormat(), который возвращает значение format, и setFormat(String), который устанавливает её значение.
Модификатор доступа public
Модификатор public — класс, метод, конструктор, интерфейс и т.д. объявленные как public могут быть доступны из любого другого класса. Поэтому поля, методы, блоки, объявленные внутри public класса могут быть доступны из любого класса, принадлежащего к «вселенной» Java.
Тем не менее, если к public классу в другом пакете мы пытаемся получить доступ, то public класс приходится импортировать.
Благодаря наследованию классов, в Java все публичные (public) методы и переменные класса наследуются его подклассами.
Пример
Следующая функция использует контроль доступа public:
Метод main() должен быть публичным (public). В противном случае, он не может быть вызван с помощью java-интерпретатора, чтобы запустить класс.
Модификатор доступа protected
Модификатор protected — переменные, методы и конструкторы, которые объявляются как protected в суперклассе, могут быть доступны только для подклассов в другом пакете или для любого класса в пакете класса protected.
Модификатор доступа protected в Java не может быть применен к классу и интерфейсам. Методы и поля могут быть объявлены как protected, однако методы и поля в интерфейсе не могут быть объявлены как protected.
Доступ protected дает подклассу возможность использовать вспомогательный метод или переменную, предотвращая неродственный класс от попыток использовать их.
Пример
Следующий родительский класс использует контроля доступа protected, чтобы его дочерний класс переопределил метод openSpeaker():
При этом, если мы определим метод openSpeaker() как protected, то он не будет доступен из любого другого класса, кроме AudioPlayer. Если мы определим его как public, то он станет доступным всем. Но наше намерение состоит в том, чтобы раскрыть этот метод только подклассу, вот почему мы использовали модификатор protected.
Правила контроля доступа и наследования
Следующие правила в Java применяются для унаследованных методов:
Модификаторы класса, метода, переменной и потока, используемые не для доступа
Java предоставляет ряд модификаторов не для доступа, а для реализации многих других функциональных возможностей:
Модификатор static
Модификатор static — применяется для создания методов и переменных класса.
Переменные static
Ключевое слово static используется для создания переменных, которые будут существовать независимо от каких-либо экземпляров, созданных для класса. Только одна копия переменной static в Java существует вне зависимости от количества экземпляров класса.
Статические переменные также известны как переменные класса. В Java локальные переменные не могут быть объявлены статическими (static).
Методы static
Ключевое слово static используется для создания методов, которые будут существовать независимо от каких-либо экземпляров, созданных для класса.
В Java статические методы или методы static не используют какие-либо переменные экземпляра любого объекта класса, они определены. Методы static принимают все данные из параметров и что-то из этих параметров вычисляется без ссылки на переменные.
Переменные и методы класса могут быть доступны с использованием имени класса, за которым следует точка и имя переменной или метода.
Пример
Модификатор static в Java используется для создания методов классов и переменных, как показано в следующем примере:
Будет получен следующий результат:
Модификатор final
Модификатор final — используется для завершения реализации классов, методов и переменных.
Переменные final
Переменная final может быть инициализирована только один раз. Ссылочная переменная, объявленная как final, никогда не может быть назначен для обозначения другого объекта.
Однако данные внутри объекта могут быть изменены. Таким образом, состояние объекта может быть изменено, но не ссылки.
С переменными в Java модификатор final часто используется со static, чтобы сделать константой переменную класса.
Пример
Методы final
Метод final не может быть переопределен любым подклассом. Как упоминалось ранее, в Java модификатор final предотвращает метод от изменений в подклассе.
Главным намерение сделать метод final будет то, что содержание метода не должно быть изменено стороне.
Пример
Объявление метода, использующего модификатор final в объявление класса, показано в следующем примере:
Класс final
Основная цель в Java использования класса объявленного в качестве final заключается в предотвращении класс от быть подклассом. Если класс помечается как final, то ни один класс не может наследовать любую функцию из класса final.
Пример
Модификатор abstract
Модификатор abstract — используется для создания абстрактных классов и методов.
Класс abstract
Класс abstract не может создать экземпляр. Если класс объявлен как abstract, то единственная цель для него быть расширенным.
Класс не может быть одновременно abstract и final, так как класс final не может быть расширенным. Если класс содержит абстрактные методы, то он должен быть объявлен как abstract. В противном случае будет сгенерирована ошибка компиляции.
Класс abstract может содержать как абстрактные методы, а также и обычные.
Пример
Метод abstract
Метод abstract является методом, объявленным с любой реализацией. Тело метода (реализация) обеспечивается подклассом. Методы abstract никогда не могут быть final или strict.
Любой класс, который расширяет абстрактный класс должен реализовать все абстрактные методы суперкласса, если подкласс не является абстрактным классом.
Если класс в Java содержит один или несколько абстрактных методов, то класс должен быть объявлен как abstract. Абстрактный класс не обязан содержать абстрактные методы.
Абстрактный метод заканчивается точкой с запятой. Пример: public abstract sample();
Пример
Модификатор synchronized
Модификатор synchronized — используются в Java для потоков.
Ключевое слово synchronized используется для указания того, что метод может быть доступен только одним потоком одновременно. В Java модификатор synchronized может быть применен с любым из четырех модификаторов уровня доступа.
Пример
Модификатор transient
Переменная экземпляра отмеченная как transient указывает виртуальной машине Java (JVM), чтобы пропустить определённую переменную при сериализации объекта, содержащего её.
Этот модификатор включён в оператор, что создает переменную, предшествующего класса или типа данных переменной.
Пример
Модификатор volatile
Модификатор volatile — используются в Java для потоков.
В Java модификатор volatile используется, чтобы позволить знать JVM, что поток доступа к переменной всегда должен объединять свою собственную копию переменной с главной копией в памяти.
Доступ к переменной volatile синхронизирует все кэшированные скопированные переменные в оперативной памяти. Volatile может быть применен только к переменным экземпляра, которые имеют тип объект или private. Ссылка на объект volatile может быть null.
Пример
Как правило, run() вызывается в одном потоке (впервые начинаете использовать Runnable в Java), а stop() вызывается из другого потока. Если в линии 1 используется кэшированное значение active, то цикл не может остановиться, пока Вы не установите active false в линии 2.
В следующем уроке обсудим основные операторы, используемые в языке Java. Этот раздел даст Вам обзор того, как можно использовать их во время разработки приложения.
Модификаторы доступа Java
Модификаторы доступа Java. ключевое слово public private protected для контроля доступа. примеры java private, java protected, java public. Спецификаторы доступа Java.
Модификаторы доступа Java
Мы можем использовать модификаторы доступа java с классами, а также переменными и методами классов.
Нам разрешено использовать только модификаторы доступа “общедоступный” или “по умолчанию” с классами java.
Модификаторы доступа Java с членом класса
У нас могут быть все четыре модификатора доступа для переменных и методов-членов класса. Однако правила модификатора доступа к членам применяются после правил доступа на уровне класса. Например, если класс имеет доступ по умолчанию, то он не будет виден в других пакетах, и, следовательно, методы и переменные класса также не будут видны.
Мы рассмотрим каждый из них отдельно, а затем покажем использование модификаторов доступа java с помощью простой программы.
Модификаторы доступа Java – ключевое слово public
Если член класса является “общедоступным”, то к нему можно получить доступ из любого места. Доступ к переменной – члену или методу осуществляется глобально. Это самый простой способ предоставить доступ членам класса. Однако мы должны позаботиться об использовании этого ключевого слова с переменными класса, иначе любой может изменить значения. Обычно переменные класса хранятся как частные, и для работы с ними предоставляются методы getter-setter.
Модификаторы доступа Java – частное ключевое слово
Если член класса является “частным”, то он будет доступен только внутри того же класса. Это самый ограниченный доступ, и член класса не будет виден внешнему миру. Обычно мы сохраняем переменные класса как частные, а методы, которые предназначены для использования только внутри класса, как частные.
Модификаторы доступа Java – защищенное ключевое слово
Если член класса “защищен”, то он будет доступен только классам в том же пакете и подклассам . Этот модификатор менее ограничен для частного, но более ограничен для публичного доступа. Обычно мы используем это ключевое слово, чтобы убедиться, что переменные класса доступны только подклассам.
Модификаторы доступа Java – доступ по умолчанию
Если у члена класса не указан какой-либо модификатор доступа, то он обрабатывается доступом по умолчанию. Правила доступа аналогичны классам, и член класса с доступом по умолчанию будет доступен только классам в одном пакете. Этот доступ более ограничен, чем публичный, и защищен, но менее ограничен, чем частный.
(Наименее доступный) частный Метки



