Какой модификатор доступа в Java предоставляет доступ элементам того же пакета и классам-наследникам?

Ответ

Это модификатор protected.

Почему именно он? В Java protected объединяет доступность package-private (элементы того же пакета) и добавляет возможность доступа для классов-наследников, даже если они находятся в других пакетах.

Практический пример:

// Файл: com/example/animal/Animal.java
package com.example.animal;

public class Animal {
    protected String name; // Доступно в пакете и наследникам
    protected void eat() {
        System.out.println("Eating...");
    }
}
// Файл: com/example/pet/Dog.java
package com.example.pet;

import com.example.animal.Animal;

public class Dog extends Animal { // Наследник из другого пакета
    public void bark() {
        eat();    // OK: метод protected
        name = "Rex"; // OK: поле protected
    }
}

Краткая сводка по модификаторам Java:

  1. private – доступ только внутри своего класса.
  2. default (package-private) – доступ внутри пакета (модификатор не указан).
  3. protected – доступ внутри пакета + для классов-наследников.
  4. public – доступ отовсюду.

Ответ 18+ 🔞

Давай разберём этот ваш protected, а то народ путается, как последние идиоты. Представь, что у тебя есть секрет, но не совсем секрет, а типа для своих и для родни.

Вот смотри, есть у тебя класс Animal в пакете com.example.animal. Ты там объявляешь поле name и метод eat() с модификатором protected. Что это значит, блядь?

Это значит, что доступ к этой хуйне имеют:

  1. Все, кто в том же пакете (com.example.animal). Как соседи по подъезду — заходи, бери из холодильника, только не трогай мою банку с огурцами.
  2. Все классы-наследники, даже если они в другом пакете. Это как родственники из другого города. Они тоже могут приехать и взять то, что protected, потому что кровные, ёпта.

А вот какой-нибудь левый мудак из пакета com.example.unrelated, который не является ни соседом по пакету, ни наследником, — тому нихуя не светит. Он будет как собака Павлова: слюни текут, а достучаться не может.

Пример, чтобы в мозгу щёлкнуло:

// Файл: com/example/animal/Animal.java
package com.example.animal;

public class Animal {
    protected String name; // Имя — для своих и детей
    protected void eat() { // Жрать — тоже
        System.out.println("Жую...");
    }
}

А теперь наследничек из другого пакета:

// Файл: com/example/pet/Dog.java
package com.example.pet; // Другой пакет, блядь!

import com.example.animal.Animal;

public class Dog extends Animal { // Но он РОДНЯ!
    public void bark() {
        eat();    // Да без проблем, пап, пожую
        name = "Рекс"; // И имя себе поставлю, чё бухтеть-то?
    }
}

Вот и вся магия. Dog — наследник, поэтому ему можно. А если бы он не extends Animal делал, то был бы просто посторонним пиздюком и сидел бы без имени и еды.

Краткий гид по модификаторам, чтобы не ебать мозг:

  1. private – Только я, я и ещё раз я. Даже наследникам нихуя. Полная изоляция, как в камере.
  2. default (package-private) – Для своих в пакете. Как коммуналка: все соседи видят, кто в каком белье ходит, а с улицы — хуй.
  3. protected – Для соседей по пакету И для родни (наследников). Вот он, наш сегодняшний герой.
  4. public – Всё на показ, как в публичном доме. Заходи кто хочешь, бери что хочешь.