Что такое модификатор доступа protected в контексте ООП?

«Что такое модификатор доступа protected в контексте ООП?» — вопрос из категории ООП, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Модификатор protected предоставляет доступ к членам класса (полям, методам) в рамках определенной иерархии наследования и пакета. Это промежуточный уровень между private и public.

Область видимости protected-члена:

  1. Внутри самого класса, где он объявлен.
  2. Внутри любого класса, находящегося в том же пакете (как package-private).
  3. Внутри классов-наследников (подклассов), даже если они объявлены в других пакетах.

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

// Базовый класс в пакете 'com.testing.framework'
package com.testing.framework;

public abstract class BaseAssertion {
    protected String actualValue; // Protected поле видно наследникам
    protected String message; // Protected поле видно наследникам

    protected BaseAssertion(String actual) {
        this.actualValue = actual;
        this.message = "Assertion failed";
    }

    // Protected метод, который могут переопределить или использовать наследники
    protected void logComparison(String expected) {
        System.out.printf("[DEBUG] Comparing: actual='%s', expected='%s'%n", actualValue, expected);
    }

    public abstract void assertEquals(String expected);
}

// Пользовательский класс-наследник в другом пакете
package com.myapp.tests;
import com.testing.framework.BaseAssertion;

public class CustomStringAssertion extends BaseAssertion {
    public CustomStringAssertion(String actual) {
        super(actual);
    }

    @Override
    public void assertEquals(String expected) {
        // Наследник имеет прямой доступ к protected-полям и методам
        logComparison(expected); // Вызов protected метода
        if (!actualValue.equals(expected)) {
            throw new AssertionError(message + ": " + actualValue + " != " + expected);
        }
    }
}

Для QA-инженера: Понимание protected важно при анализе кодовой базы, построенной на наследовании (например, в тестовых фреймворках типа TestNG или при работе с Page Object Model). Вы будете видеть, какие методы предназначены для расширения в наследниках, а какие — полностью внутренние (private).