Рубрики
Без рубрики

Модификатор доступа Java “защищенный”

Защищенный модификатор помогает классам Java инкапсулировать свою реализацию, а также совместно использовать ее со связанными типами. Изучите, как этот модификатор работает на практике.

Автор оригинала: baeldung.

1. Обзор

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

2. Защищенное ключевое слово

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

Используя ключевое слово protected , мы принимаем решения о том, какие методы и поля следует считать внутренними элементами иерархии пакетов или классов, а какие доступны внешнему коду.

3. Объявление защищенных полей, Методов и конструкторов

Во-первых, давайте создадим класс с именем Первый класс , содержащий защищенное поле, метод и конструктор:

public class FirstClass {

    protected String name;

    protected FirstClass(String name) {
        this.name = name;
    }

    protected String getName() {
        return name;
    }
}

В этом примере, используя ключевое слово protected , мы предоставили доступ к этим полям классам в том же пакете, что и FirstClass , и подклассам FirstClass .

4. Доступ к защищенным полям, методам и конструкторам

4.1 Из Того Же пакета

Теперь давайте посмотрим, как мы можем получить доступ к защищенным полям, создав новый Универсальный класс , объявленный в том же пакете, что и FirstClass :

public class GenericClass {

    public static void main(String[] args) {
        FirstClass first = new FirstClass("random name");
        System.out.println("FirstClass name is " + first.getName());
        first.name = "new name";
    }
}

Поскольку этот вызывающий класс находится в том же пакете, что и Первый класс, ему разрешено видеть и взаимодействовать со всеми защищенными полями, методами и конструкторами.

4.2. Из другого пакета

Теперь давайте попробуем взаимодействовать с этими полями из класса, объявленного в другом пакете из First Class :

public class SecondGenericClass {

    public static void main(String[] args) {
        FirstClass first = new FirstClass("random name");
        System.out.println("FirstClass name is "+ first.getName());
        first.name = "new name";
    }
}

Как мы видим, мы получаем ошибки компиляции :

The constructor FirstClass(String) is not visible
The method getName() from the type FirstClass is not visible
The field FirstClass.name is not visible

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

4.3 Из подкласса

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

public class SecondClass extends FirstClass {
    
    public SecondClass(String name) {
        super(name);
        System.out.println("SecondClass name is " + this.getName());
        this.name = "new name";
    } 
}

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

5. защищенный Внутренний Класс

В предыдущих примерах мы видели защищенные поля, методы и конструкторы в действии. Есть еще один частный случай —/| защищенный внутренний класс.

Давайте создадим этот пустой внутренний класс внутри нашего Первого класса :

package com.baeldung.core.modifiers;

public class FirstClass {

    // ...

    protected static class InnerClass {

    }
}

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

5.1 Из Того Же пакета

Чтобы проверить это, давайте отредактируем наш Универсальный класс :

public class GenericClass {

    public static void main(String[] args) {
        // ...
        FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
    }
}

Как мы видим, мы можем создать экземпляр Внутреннего класса без каких-либо проблем, потому что Универсальный класс находится в том же пакете, что и Первый класс .

5.2. Из другой упаковки

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

public class SecondGenericClass {

    public static void main(String[] args) {
        // ...

        FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
    }
}

Как и ожидалось, мы получаем ошибку компиляции :

The type FirstClass.InnerClass is not visible

5.3. Из подкласса

Давайте попробуем сделать то же самое из нашего Второго класса :

public class SecondClass extends FirstClass {
    
    public SecondClass(String name) {
        // ...
 
        FirstClass.InnerClass innerClass = new FirstClass.InnerClass();
    }     
}

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

The constructor FirstClass.InnerClass() is not visible

Давайте взглянем на наш Внутренний класс объявление:

protected static class InnerClass {
}

Основная причина, по которой мы получаем эту ошибку, заключается в том, что конструктор по умолчанию класса protected неявно protected . Кроме того, Второй класс является подклассом первого класса, но не является подклассом внутреннего класса . Наконец, мы также объявили | Второй класс вне Первый класс’ пакет .

По всем этим причинам Второй класс не может получить доступ к защищенному | Внутреннему классу конструктору.

Если бы мы хотели решить эту проблему и позволить нашему Второму классу создать экземпляр Внутреннего класса объекта, мы могли бы явно объявить открытый конструктор :

protected static class InnerClass {
    public InnerClass() {
    }
}

Делая это, мы больше не получаем ошибку компиляции, и теперь мы можем создать экземпляр Внутреннего класса из Второго класса .

6. Заключение

В этом кратком руководстве мы обсудили модификатор protected access в Java. С его помощью мы можем обеспечить предоставление только необходимых данных и методов подклассам и классам в одном пакете.

Как всегда, пример кода доступен на GitHub .