Что такое public в java
Перейти к содержимому

Что такое public в java

  • автор:

Модификаторы доступа

Вы уже, наверное, неоднократно видели в примерах использование таких ключевых слов, как public , private и protected . Это модификаторы доступа в языке Java. Сегодня мы рассмотрим для чего они используются.

Очень часто в Java доступ к некоторым членам класса желательно ограничить. Для этого и нужны модификаторы доступа, которые могут присутствовать в объявлении члена класса. Модификатор доступа указывается перед остальной спецификации типа члена, например:

public int i; private static double j; private int myMethod (int а , char b ) < / / . . .

Существует три модификатора доступа: public , private и protected и четыре уровня доступа:

  1. public (открытый) - когда член объявляется с модификатором доступа public , он становится доступным из любого другого кода.
  2. private (закрытый) - когда член класса объявляется с модификатором доступа private , он доступен только другим членам этого же класса.
  3. protected (защищенный) - применяется только при наследовании.
  4. Уровень доступа, предоставляемый по умолчанию - в отсутствие модификатора доступа по умолчанию член класса считается открытым в своем пакете, но недоступным для кода, находящегося за пределами этого пакета.

Ограничение уровня доступа к членам класса - это еще один механизм реализации принципа инкапсуляции.

2. Отличие уровня доступа по умолчанию, public и private

Рассмотрим отличие уровня доступа по умолчанию, public и private на следующем примере. В классе Modificators объявлено три переменные с разным уровнем доступа. Внутри самого класса Modificators можно обратится к любой из этих переменных, как показано в методе toString() :

package oop; public class Modificators < public int publicVar; // открытый уровень доступа private int privateVar; // закрытый уровень доступа int defaultVar; // уровень доступа по умолчанию public String toString() < return "Modificatorspackage oop; public class ModificatorsDemo1 < public static void main(String[] args) < Modificators object = new Modificators(); object.defaultVar = 10; object.publicVar = 20; //object.privateVar = 100; // Ошибка компиляции! >>

Создадим класс похожий на ModificatorsDemo1 , но в другом пакете. В этом классе мы точно также не можем обратиться к private переменной, но теперь и переменная с уровнем доступа по умолчанию тоже недоступна:

package oop.p2; import oop.Modificators; public class ModificatorsDemo2 < public static void main(String[] args) < Modificators object = new Modificators(); //object.defaultVar = 10;// Ошибка компиляции! object.publicVar = 20; //object.privateVar = 100; // Ошибка компиляции! >>

3. Уровень доступа protected в Java

Уровень доступа protected используется при наследовании. Он очень похож на уровень доступа по умолчанию, который раскрывает область видимости только для классов определенных в том же пакете. Protected модификатор раскрывает область видимости для классов определенных в том же пакете или для классов наследников.

Рассмотрим разницу между уровнями доступа на следующем примере.

Объявим в классе Parent три метода с разными уровнями доступа:

package oop.p1; public class Parent < public void publicAccessMethod() < >void defaultAccessMethod() < >protected void protectedAccessMethod() < >> 

Определяем класс наследник в другом пакете:

package oop.p2; import oop.p1.Parent; public class Child extends Parent < public void someMethod() < publicAccessMethod(); //defaultAccessMethod(); protectedAccessMethod(); >>

Из класса Child нет доступа к default членам класса Parent , но есть доступ к protected и public членам класса Parent .

Рассмотрим следующий класс - AccessClass , находящийся в пакете отличном от класса Parent . Он не является наследником Parent , поэтому доступ из него разрешен только к public методам:

package oop.p2; import oop.p1.Parent; public class AccessClass < public static void main(String[] args) < Parent parent = new Parent(); parent.publicAccessMethod(); // parent.defaultAccessMethod(); // parent.protectedAccessMethod(); >>

Перенесем класс AccessClass в пакет, в котором находится класс Parent , и мы получим доступ не только к public членам класса, но и к protected и default :

package oop.p1; public class AccessClass < public static void main(String[] args) < Parent parent = new Parent(); parent.publicAccessMethod(); parent.defaultAccessMethod(); parent.protectedAccessMethod(); >> 

4. Уровни доступа для класса

Для класса, не являющегося вложенным, может быть указан только один из двух возможных уровней доступа:

  • По умолчанию - если у класса имеется уровень доступа по умолчанию, такой класс оказывается доступным только для кода из данного пакета.
  • Открытый ( public ) - если класс объявлен как public , он доступен из любого другого кода.

Когда мы говорим, что код из одного класса ( class A ) имеет доступ к коду из другого класса ( class B ), это означает что класс A может делать одну из трех вещей:

  • создать экземпляр класса B ,
  • наследовать класс B ,
  • иметь доступ к определенным членам класса B .

В этом примере показана попытка наследовать класс HotBevarage с уровнем доступа по умолчанию из другого пакета. В этом случае возникнет ошибка компиляции:

package oop.p1; class HotBeverage<> 
package oop.p2; //import oop.p1.HotBeverage; public class Tea //extends HotBeverage<> 

Если класс оказывается открытым, он должен быть единственным открытым классом, объявленным в файле, а имя этого файла должно совпадать с именем класса. Например:

public class Beverage <> class HotBeverage<> 
  • Процедурное и объектно-ориентированное программирование
  • Принципы ООП
  • Классы и объекты
  • Конструктор
  • Ключевое слово this
  • Перегрузка
  • Стек и куча
  • Передача объектов в методы
  • Java varargs
  • Рекурсия
  • Сборщик мусора и метод finalize
  • Наследование
  • Ключевое слово super
  • Геттеры и сеттеры
  • Переопределение методов
  • Абстрактные классы и методы
  • Ключевое слово final
  • Задания

Что такое public в Java?

В языке Java ключевое слово public является модификатором доступа, определяющим видимость классов, полей и методов для других классов и пакетов. Когда элемент объявлен с модификатором public , он доступен из любого места в программе, даже за пределами текущего пакета.

Примеры:

  • Если поле объявлено с модификатором public , оно может быть доступно и изменено из других классов.
public int publicField = 10;
  • Если метод объявлен с модификатором public , он становится доступным для вызова из любого другого класса.
public void publicMethod() < // код метода >
  • Если класс объявлен с модификатором public , его можно использовать из любого другого класса.
public class PublicClass < // код класса >

9. Java – Модификаторы доступа и класса

Модификаторы – ключевые слова, которые Вы добавляете при инициализации для изменения значений. Язык Java имеет широкий спектр модификаторов, основные из них:

  • модификаторы доступа;
  • модификаторы класса, метода, переменной и потока, используемые не для доступа.

Чтобы использовать модификатор в Java, нужно включить его ключевое слово в определение класса, метода или переменной. Модификатор должен быть впереди остальной части оператора, как показано в следующих примерах:

 private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) < // тело метода >

Модификаторы доступа

Java предоставляет ряд модификаторов доступа, чтобы задать уровни доступа для классов, переменных, методов и конструкторов. Существует четыре доступа:

  • Видимый в пакете (стоит по умолчанию и модификатор не требуются).
  • Видимый только для класса (private).
  • Видимый для всех (public).
  • Видимый для пакета и всех подклассов (protected).

Модификатор доступа по умолчанию – без ключевого слова

Модификатор доступа по умолчанию – означает, что мы явно не объявляем модификатор доступа в Java для класса, поля, метода и т.д.

Переменная или метод, объявленные без модификатора контроля доступа доступны для любого другого класса в том же пакете. Поля в интерфейсе неявно являются public, static, final, а методы в интерфейсе по умолчанию являются public.

Пример

Переменные и методы могут быть объявлены в Java без каких-либо модификаторов, как показано в следующем примере:

Модификатор доступа private

Модификатор private – методы, переменные и конструкторы, которые объявлены как private в Java могут быть доступны только в пределах самого объявленного класса.

Модификатор доступа private является наиболее ограничивающим уровенем доступа. Класс и интерфейсы не могут быть private.

Переменные, объявленные как private, могут быть доступны вне класса, если получающие их открытые (public) методы присутствуют в классе (ниже смотрите пример и пояснения).

Использование модификатора private в Java является основным способом, чтобы скрыть данные.

Пример

Следующий класс использует контроль доступа private:

 public void setFormat(String format) < this.format = format; >> 

Здесь переменная 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():

 > class StreamingAudioPlayer < boolean openSpeaker(Speaker sp) < // детали реализации >> 

При этом, если мы определим метод openSpeaker() как protected, то он не будет доступен из любого другого класса, кроме AudioPlayer. Если мы определим его как public, то он станет доступным всем. Но наше намерение состоит в том, чтобы раскрыть этот метод только подклассу, вот почему мы использовали модификатор protected.

Правила контроля доступа и наследования

Следующие правила в Java применяются для унаследованных методов:

  • Методы, объявленные как public в суперклассе, также должны быть public во всех подклассах.
  • Методы, объявленные как protected в суперклассе, должны либо быть либо protected, либо public в подклассах; они не могут быть private.
  • Методы, объявленные как private для всех не наследуются, так что нет никакого правила для них.

Модификаторы класса, метода, переменной и потока, используемые не для доступа

Java предоставляет ряд модификаторов не для доступа, а для реализации многих других функциональных возможностей:

  • модификатор static применяется для создания методов и переменных класса;
  • модификатор final используется для завершения реализации классов, методов и переменных;
  • модификатор abstract необходим для создания абстрактных классов и методов;
  • модификаторы synchronized и volatile используются в Java для потоков.

Модификатор static

Модификатор static – применяется для создания методов и переменных класса.

Переменные static

Ключевое слово static используется для создания переменных, которые будут существовать независимо от каких-либо экземпляров, созданных для класса. Только одна копия переменной static в Java существует вне зависимости от количества экземпляров класса.

Статические переменные также известны как переменные класса. В Java локальные переменные не могут быть объявлены статическими (static).

Методы static

Ключевое слово static используется для создания методов, которые будут существовать независимо от каких-либо экземпляров, созданных для класса.

В Java статические методы или методы static не используют какие-либо переменные экземпляра любого объекта класса, они определены. Методы static принимают все данные из параметров и что-то из этих параметров вычисляется без ссылки на переменные.

Переменные и методы класса могут быть доступны с использованием имени класса, за которым следует точка и имя переменной или метода.

Пример

Модификатор static в Java используется для создания методов классов и переменных, как показано в следующем примере:

 private static void addInstance() < numInstances++; >InstanceCounter() < InstanceCounter.addInstance(); >public static void main(String[] arguments) < System.out.println("Начиная с " + InstanceCounter.getCount() + " экземпляра"); for (int i = 0; i < 500; ++i)< new InstanceCounter(); >System.out.println("Создано " + InstanceCounter.getCount() + " экземпляров"); > > 

Будет получен следующий результат:

Модификатор 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();

Пример
 class SubClass extends SuperClass < // реализует абстрактный метод void m()< . >> 

Модификатор synchronized

Модификатор synchronized – используются в Java для потоков.

Ключевое слово synchronized используется для указания того, что метод может быть доступен только одним потоком одновременно. В Java модификатор synchronized может быть применен с любым из четырех модификаторов уровня доступа.

Пример

Модификатор transient

Переменная экземпляра отмеченная как transient указывает виртуальной машине Java (JVM), чтобы пропустить определённую переменную при сериализации объекта, содержащего её.

Этот модификатор включён в оператор, что создает переменную, предшествующего класса или типа данных переменной.

Пример

Модификатор volatile

Модификатор volatile – используются в Java для потоков.

В Java модификатор volatile используется, чтобы позволить знать JVM, что поток доступа к переменной всегда должен объединять свою собственную копию переменной с главной копией в памяти.

Доступ к переменной volatile синхронизирует все кэшированные скопированные переменные в оперативной памяти. Volatile может быть применен только к переменным экземпляра, которые имеют тип объект или private. Ссылка на объект volatile может быть null.

Пример
 > public void stop() < active = false; // линия 2 >> 

Как правило, run() вызывается в одном потоке (впервые начинаете использовать Runnable в Java), а stop() вызывается из другого потока. Если в линии 1 используется кэшированное значение active, то цикл не может остановиться, пока Вы не установите active false в линии 2.

В следующем уроке обсудим основные операторы, используемые в языке Java. Этот раздел даст Вам обзор того, как можно использовать их во время разработки приложения.

Оглавление

  • 1. Java – Самоучитель для начинающих
  • 2. Java – Обзор языка
  • 3. Java – Установка и настройка
  • 4. Java – Синтаксис
  • 5. Java – Классы и объекты
  • 6. Java – Конструкторы
  • 7. Java – Типы данных и литералы
  • 8. Java – Типы переменных
  • 9. Java – Модификаторы
  • 10. Java – Операторы
  • 11. Java – Циклы и операторы цикла
  • 11.1. Java – Цикл while
  • 11.2. Java – Цикл for
  • 11.3. Java – Улучшенный цикл for
  • 11.4. Java – Цикл do..while
  • 11.5. Java – Оператор break
  • 11.6. Java – Оператор continue
  • 12. Java – Операторы принятия решений
  • 12.1. Java – Оператор if
  • 12.2. Java – Оператор if..else
  • 12.3. Java – Вложенный оператор if
  • 12.4. Java – Оператор switch..case
  • 12.5. Java – Условный оператор (? 🙂
  • 13. Java – Числа
  • 13.1. Java – Методы byteValue(), shortValue(), intValue(), longValue(), floatValue(), doubleValue()
  • 13.2. Java – Метод compareTo()
  • 13.3. Java – Метод equals()
  • 13.4. Java – Метод valueOf()
  • 13.5. Java – Метод toString()
  • 13.6. Java – Метод parseInt()
  • 13.7. Java – Метод Math.abs()
  • 13.8. Java – Метод Math.ceil()
  • 13.9. Java – Метод Math.floor()
  • 13.10. Java – Метод Math.rint()
  • 13.11. Java – Метод Math.round()
  • 13.12. Java – Метод Math.min()
  • 13.13. Java – Метод Math.max()
  • 13.14. Java – Метод Math.exp()
  • 13.15. Java – Метод Math.log()
  • 13.16. Java – Метод Math.pow()
  • 13.17. Java – Метод Math.sqrt()
  • 13.18. Java – Метод Math.sin()
  • 13.19. Java – Метод Math.cos()
  • 13.20. Java – Метод Math.tan()
  • 13.21. Java – Метод Math.asin()
  • 13.22. Java – Метод Math.acos()
  • 13.23. Java – Метод Math.atan()
  • 13.24. Java – Метод Math.atan2()
  • 13.25. Java – Метод Math.toDegrees()
  • 13.26. Java – Метод Math.toRadians()
  • 13.27. Java – Метод Math.random()
  • 14. Java – Символы
  • 14.1. Java – Метод Character.isLetter()
  • 14.2. Java – Метод Character.isDigit()
  • 14.3. Java – Метод Character.isWhitespace()
  • 14.4. Java – Метод Character.isUpperCase()
  • 14.5. Java – Метод Character.isLowerCase()
  • 14.6. Java – Метод Character.toUpperCase()
  • 14.7. Java – Метод Character.toLowerCase()
  • 14.8. Java – Метод Character.toString()
  • 15. Java – Строки
  • 15.1. Java – Метод charAt()
  • 15.2. Java – Метод compareTo()
  • 15.3. Java – Метод compareToIgnoreCase()
  • 15.4. Java – Метод concat()
  • 15.5. Java – Метод contentEquals()
  • 15.6. Java – Метод copyValueOf()
  • 15.7. Java – Метод endsWith()
  • 15.8. Java – Метод equals()
  • 15.9. Java – Метод equalsIgnoreCase()
  • 15.10. Java – Метод getBytes()
  • 15.11. Java – Метод getChars()
  • 15.12. Java – Метод hashCode()
  • 15.13. Java – Метод indexOf()
  • 15.14. Java – Метод intern()
  • 15.15. Java – Метод lastIndexOf()
  • 15.16. Java – Метод length()
  • 15.17. Java – Метод matches()
  • 15.18. Java – Метод regionMatches()
  • 15.19. Java – Метод replace()
  • 15.20. Java – Метод replaceAll()
  • 15.21. Java – Метод replaceFirst()
  • 15.22. Java – Метод split()
  • 15.23. Java – Метод startsWith()
  • 15.24. Java – Метод subSequence()
  • 15.25. Java – Метод substring()
  • 15.26. Java – Метод toCharArray()
  • 15.27. Java – Метод toLowerCase()
  • 15.28. Java – Метод toString()
  • 15.29. Java – Метод toUpperCase()
  • 15.30. Java – Метод trim()
  • 15.31. Java – Метод valueOf()
  • 15.32. Java – Классы StringBuilder и StringBuffer
  • 15.32.1. Java – Метод append()
  • 15.32.2. Java – Метод reverse()
  • 15.32.3. Java – Метод delete()
  • 15.32.4. Java – Метод insert()
  • 15.32.5. Java – Метод replace()
  • 16. Java – Массивы
  • 17. Java – Дата и время
  • 18. Java – Регулярные выражения
  • 19. Java – Методы
  • 20. Java – Потоки ввода/вывода, файлы и каталоги
  • 20.1. Java – Класс ByteArrayInputStream
  • 20.2. Java – Класс DataInputStream
  • 20.3. Java – Класс ByteArrayOutputStream
  • 20.4. Java – Класс DataOutputStream
  • 20.5. Java – Класс File
  • 20.6. Java – Класс FileReader
  • 20.7. Java – Класс FileWriter
  • 21. Java – Исключения
  • 21.1. Java – Встроенные исключения
  • 22. Java – Вложенные и внутренние классы
  • 23. Java – Наследование
  • 24. Java – Переопределение
  • 25. Java – Полиморфизм
  • 26. Java – Абстракция
  • 27. Java – Инкапсуляция
  • 28. Java – Интерфейсы
  • 29. Java – Пакеты
  • 30. Java – Структуры данных
  • 30.1. Java – Интерфейс Enumeration
  • 30.2. Java – Класс BitSet
  • 30.3. Java – Класс Vector
  • 30.4. Java – Класс Stack
  • 30.5. Java – Класс Dictionary
  • 30.6. Java – Класс Hashtable
  • 30.7. Java – Класс Properties
  • 31. Java – Коллекции
  • 31.1. Java – Интерфейс Collection
  • 31.2. Java – Интерфейс List
  • 31.3. Java – Интерфейс Set
  • 31.4. Java – Интерфейс SortedSet
  • 31.5. Java – Интерфейс Map
  • 31.6. Java – Интерфейс Map.Entry
  • 31.7. Java – Интерфейс SortedMap
  • 31.8. Java – Класс LinkedList
  • 31.9. Java – Класс ArrayList
  • 31.10. Java – Класс HashSet
  • 31.11. Java – Класс LinkedHashSet
  • 31.12. Java – Класс TreeSet
  • 31.13. Java – Класс HashMap
  • 31.14. Java – Класс TreeMap
  • 31.15. Java – Класс WeakHashMap
  • 31.16. Java – Класс LinkedHashMap
  • 31.17. Java – Класс IdentityHashMap
  • 31.18. Java – Алгоритмы Collection
  • 31.19. Java – Iterator и ListIterator
  • 31.20. Java – Comparator
  • 32. Java – Дженерики
  • 33. Java – Сериализация
  • 34. Java – Сеть
  • 34.1. Java – Обработка URL
  • 35. Java – Отправка Email
  • 36. Java – Многопоточность
  • 36.1. Java – Синхронизация потоков
  • 36.2. Java – Межпоточная связь
  • 36.3. Java – Взаимная блокировка потоков
  • 36.4. Java – Управление потоками
  • 37. Java – Основы работы с апплетами
  • 38. Java – Javadoc

Модификаторы private, protected, public в Java

Модификаторы доступа private, protected, public ставятся перед именем класса, метода или поля и ограничивают доступ к нему. К локальным переменным модификаторы доступа не применимы.
Помимо этих трех явных модификаторов, есть еще так называемый default-модификатор, или модификатор по умолчанию, иначе говоря — это отсутствие всякого модификатора. Но это отсутствие тоже подразумевает свои правила доступа (видимость только внутри пакета).

Зачем нужны модификаторы доступа

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

Нормально сделать видимым, например, один класс вашего пакета и только методы, предназначенные для внешнего использования (методы API). Все остальное скрыть. Это называется инкапсуляцией (скрытием реализации).

Правила доступа

На картинке показаны правила доступа к полю или методу с конкретным модификатором (последний столбец — про модули, они появились в Java 9):

Модификаторы доступа в Java

Модификатор private

Это самый ограничивающий модификатор. К полям и методам, помеченным ключевым словом private, можно обратиться только из того же класса, где они находятся.

Допустим у нас есть класс A с private полем privateVar и с private методом privateMethod(). Из класса A мы можем обращаться к полю, см. обращение this.privateVar:

package accessmodifiers.priv; public class A < private int privateVar = 1; private void privateMethod() < System.out.println("A private method is printing " + this.privateVar); >public static void main(String[] args) < A a = new A(); a.privateVar = 2; a.privateMethod(); >>

А теперь попробуем обратиться к этому полю и методу из класса B, код не скомпилируется:

package accessmodifiers.priv; public class B < void testAccess() < A a = new A(); a.privateVar = 10; // illegal a.privateMethod(); // illegal >>

Вышеприведенный код выдает ошибки компиляции:

The field A.privateVar is not visible The method privateMethod() from the type A is not visible

Иногда возникает вопрос

Можно ли в классе A получить доступ к private методам и полям другого объекта A (не текущего this)?

Да, можно. Обратите внимание на функцию main() из класса A, в которой создается новый объект A и идет обращение к его методам и полям (не через this):

package accessmodifiers.priv; public class A < private int privateVar = 1; private void privateMethod() < System.out.println("A private method is printing " + this.privateVar); >public static void main(String[] args) < A a = new A(); a.privateVar = 2; a.privateMethod(); >>

Как показано выше, мы обращаемся в методе main() к private полю privateVar другого объекта A, и это законно.

В Java ограничения доступа применимы на уровне класса, а не на уровне объекта (не обязательно, чтоб обращение шло к тому же экземпляру, главное, что он в том же классе). В Scala, например, существуют модификаторы доступа на уровне объекта

Можно ли переопределить private метод?

Нельзя, метод в подклассе не будет иметь никакого отношения к методу в суперклассе, так как private метод нигде не виден. Давайте попытаемся унаследоваться от класса A и «переопределить» private метод privateMethod():

public class SubA extends A < private void privateMethod() < System.out.println("B private method is printing "); >>

Попробуем создать объект SubA и вызвать privateMethod() на A:

A a=new SubA(); a.privateMethod();

Как видите, срабатывает метод privateMethod() класса A, то есть переопределения не происходит:

A private method is printing 2

Это происходит потому, что метод privateMethod() класса SubA не переопределяет метод privateMethod() класса A, а является независимым методом.

Модификатор default

Если мы не ставим никакого модификатора доступа перед методом, полем или классом, то этот метод/поле/класс видимы из кода только внутри пакета, в котором они находятся.

Давайте продемонстрируем это. Создадим снова класс A в пакете .def:

package ru.sysout.accessmodifiers.def; public class A < int defaultVar = 1; void defaultMethod() < System.out.println("A default method is printing " + this.defaultVar ); >>

И создадим в этом же пакете класс B, из которого будем пытаться получить доступ к полям и методам A, как и раньше:

package ru.sysout.accessmodifiers.def; public class B < void testAccess() < A a = new A(); a.defaultVar = 10; // legal a.defaultMethod(); // legal >>

В этот раз код компилируется, все в порядке — доступ есть.

Если бы класс B находится в другом пакете (отличном от ru.sysout.accessmodifiers.def, в том числе в подпакете), то доступа бы не было.

Модификатор protected

Следующий по строгости — модификатор protected. Он также разрешает доступ к помеченным с помощью него полям и методам из кода внутри того же пакета. Но помимо этого, он дает поблажки подклассам, находящимся в другом пакете. Подкласс может обращаться к protected полям и методам суперкласса, даже если подкласс находится в другом пакете.

Снова создадим класс A с protected полем и методом:

package ru.sysout.accessmodifiers.prot; public class A < protected int protectedVar = 1; protected void protectedMethod() < System.out.println("A protected method is printing " + this.protectedVar); >>

Создадим в другом пакете класс C — наследника класса A и попытаемся получить доступ к полям методам класса A из класса C:

package ru.sysout.accessmodifiers.prot.sub; import ru.sysout.accessmodifiers.prot.A; public class C extends A < void testAccess(A a, C c) < this.protectedVar = 1;// legal this.protectedMethod();// legal // a.protectedVar = 10; // illegal c.protectedVar = 10; // legal // a.protectedMethod(); // illegal c.protectedMethod(); // legal >>

Как показано выше, обращение к полю и методу через this работает из другого пакета.

Также работает обращение ко всем другим экземплярам типа C, но к другим экземплярам типа A обращение не работает.

Модификатор public

Тут все просто — к полю и методу с модификатором public имеет доступ любой код. Давайте еще раз перепишем класс A:

package ru.sysout.accessmodifiers.pub; public class A < public int publicVar = 1; public void publicMethod() < System.out.println("A public method is printing " + this.publicVar); >>

И обратимся к его полю и методу из класса B, который находится в другом пакете и никакого отношения к классу A не имеет:

package ru.sysout.accessmodifiers.pub.sub; import ru.sysout.accessmodifiers.pub.A; public class B < void testAccess() < A a = new A(); a.publicVar = 10; // legal a.publicMethod(); // legal >>

Все получилось, обращение работает.

Какой модификатор выбрать?

Правило выбора модификатора такое — надо по возможности выбирать:

То есть надо максимально ограничивать видимость члена класса. Сначала надо попробовать сделать все private, и при необходимости открывать видимость.

Итог

Мы рассмотрели тонкости использования модификаторов доступа. Код примеров можно посмотреть на GitHub.

Автор sysout Опубликовано 26.09.2018 16.11.2022 Рубрики Core Java

Модификаторы private, protected, public в Java: 2 комментария

В разделе «Может ли объект A получить доступ к private методам и полям другого объекта A?» код не соответствует смыслу написанного — пожалуйста исправьте его

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *