Ответ
В Java четыре модификатора доступа, которые контролируют видимость классов, методов и полей. Их применение основано на принципе инкапсуляции.
Сравнительная таблица
| Модификатор | Уровень класса | Уровень пакета | Подклассы (наследники) | Остальной мир (другие пакеты) |
|---|---|---|---|---|
private |
Да | Нет | Нет | Нет |
default (package-private) |
Да | Да | Нет* | Нет |
protected |
Да | Да | Да | Нет |
public |
Да | Да | Да | Да |
*Подкласс, находящийся в другом пакете, не имеет доступа к default-членам родительского класса.
Примеры и использование
package com.example;
public class AccessExample {
private String secret = "Доступ только внутри AccessExample"; // Полная инкапсуляция
String packagePrivate = "Доступ в пакете com.example"; // Default (без модификатора)
protected void inheritMe() { // Доступ в пакете и подклассах
System.out.println("Метод для наследников");
}
public static final String API_CONSTANT = "PUBLIC"; // Открытый API
}
// В другом пакете
package com.other;
import com.example.AccessExample;
class SubClass extends AccessExample {
void test() {
// System.out.println(secret); // Ошибка: private
// System.out.println(packagePrivate); // Ошибка: default (другой пакет)
inheritMe(); // OK: protected (наследник)
System.out.println(AccessExample.API_CONSTANT); // OK: public
}
}
Практические рекомендации
private— основной инструмент для сокрытия внутренней реализации. Делайте поля приватными, предоставляя доступ через геттеры/сеттеры.default— используйте осознанно для связи внутри модуля или пакета, когда функциональность не является частью публичного API.protected— применяйте в классах, предназначенных для наследования, чтобы предоставить наследникам доступ к внутренним вспомогательным методам.public— минимально необходимый набор для API класса. Избегайте публичных полей (кроме константstatic final).
Правило: Давайте минимально необходимый уровень доступа. Начинайте с private и расширяйте его только при явной необходимости.