Ответ
В Java существует четыре основных модификатора доступа, которые определяют видимость классов, методов и полей. Упорядочены от самого строгого к самому открытому:
private: Элемент доступен только внутри класса, в котором он объявлен. Это максимальный уровень инкапсуляции.default(package-private): Элемент доступен только внутри своего пакета. Используется, когда модификатор доступа не указан явно.protected: Элемент доступен внутри своего пакета, а также классам-наследникам (subclasses), даже если они находятся в других пакетах.public: Элемент доступен из любого другого класса.
| Сводная таблица видимости: | Модификатор | Класс | Пакет | Подкласс (другой пакет) | Весь мир |
|---|---|---|---|---|---|
private |
Да | Нет | Нет | Нет | |
default |
Да | Да | Нет | Нет | |
protected |
Да | Да | Да | Нет | |
public |
Да | Да | Да | Да |
Пример в коде:
package com.example;
public class AccessModifiersDemo {
private String secret = "Только для этого класса";
String packagePrivate = "Для классов пакета com.example"; // default
protected String forSubclasses = "Для пакета и наследников";
public String api = "Для всех";
private void privateMethod() {}
public void publicMethod() {
// Внутри класса доступно всё
System.out.println(secret);
}
}
// Класс в другом пакете
package com.other;
import com.example.AccessModifiersDemo;
class OtherPackageClass extends AccessModifiersDemo {
void test() {
// System.out.println(secret); // Ошибка: private
// System.out.println(packagePrivate); // Ошибка: default
System.out.println(forSubclasses); // OK: protected (наследник)
System.out.println(api); // OK: public
}
}
Примечание для C#: В C# используются схожие модификаторы public, protected, private, а также internal (аналог Java default) и protected internal (объединение protected и internal).
Ответ 18+ 🔞
А, ну это про наши любимые модификаторы доступа в Java, да? Ёпта, классика, как "Муму" Тургенева, только проще, блядь. Сейчас разжуём, как бабка семечки.
Смотри, есть у нас четыре таких охранника, которые решают, кто и куда может совать свой нос. Идут они, как водка по градусам — от самой жёсткой до той, что всех на уши ставит.
Первый, private — это как твой личный дневник в запертом ящике. Только сам класс, в котором это объявлено, может туда лазить. Никакой сосед по пакету, никакой сын-наследник — нихуя. Максимальная закрытость, инкапсуляция в её, блядь, чистейшем виде. Секретики свои храни.
Второй, default (он же package-private). Во, это интересно! Его даже писать не надо, просто ни хуя не ставишь. Доступ — только для своих, для членов одного пакета. Как в коммуналке: все, кто живёт в квартире com.example, могут брать твою соль, но сосед из com.other — уже нет. Семейное, так сказать.
Третий, protected. А вот это уже хитрая жопа. Он как default, но с бонусом для родни. То есть доступ даётся и всему пакету, и ещё всем детям-наследникам, даже если они уехали жить в другой пакет. Типа, "семья — это святое, где бы ты ни был".
Четвёртый, public. Ну тут всё просто, ёпта. Полная открытость, как площадь в праздник. Объявил что-то public — и будь добр, любой урод из любого уголка программы может к этому прикоснуться. Ответственность, блядь, овердохуища.
А вот тебе табличка, чтобы в голове не еблось:
| Модификатор | Сам класс | Свой пакет | Наследник (чужой пакет) | Весь мир |
|---|---|---|---|---|
private |
Да | Нет | Нет | Нет |
default |
Да | Да | Нет | Нет |
protected |
Да | Да | Да | Нет |
public |
Да | Да | Да | Да |
Ну и кусочек кода, чтобы было понятнее, где что торчит:
package com.example;
public class AccessModifiersDemo {
private String secret = "Только для этого класса";
String packagePrivate = "Для классов пакета com.example"; // default
protected String forSubclasses = "Для пакета и наследников";
public String api = "Для всех";
private void privateMethod() {}
public void publicMethod() {
// Внутри класса доступно всё
System.out.println(secret);
}
}
// Класс в другом пакете
package com.other;
import com.example.AccessModifiersDemo;
class OtherPackageClass extends AccessModifiersDemo {
void test() {
// System.out.println(secret); // Ошибка: private — нихуя не получишь
// System.out.println(packagePrivate); // Ошибка: default — ты не из нашего пакета
System.out.println(forSubclasses); // OK: protected — ты же сын, проходи
System.out.println(api); // OK: public — welcome, блядь
}
}
И да, для тех, кто из мира C# подъехал: у вас там почти так же, только internal — это наш default, а protected internal — это такая помесь, чтоб её. В общем, суть одна, просто вывеска другая.