Защищенное поведение члена после того, как оно было унаследовано.


У меня есть некоторые сомнения относительно защищенного идентификатора. В первой главе учебного пособия Sun Certified Java Programmer by K. Sierra я нашел следующую информацию:

"Как только подкласс-вне-пакета наследует защищенный элемент, этот элемент (как наследуется подклассом) становится частным для любого кода вне подкласса, за исключением подклассов подкласса."

Я предоставил пример кода, который отражает приведенное выше утверждение, и это абсолютно ясно для меня.

// Parent class
package package1;

import package2.Child;
public class Parent {

    protected int i = 5;

}

// Child class
package package2;

import package1.Parent;

public class Child extends Parent {

    // variable 'i' inherited

}


package package2;

public class Neighbour {

    public void protectedTesting(){
        Child child = new Child();
        System.out.println(child.i); // no access
    }
}

Я начал экспериментировать и сделал небольшое изменение-переместил соседа в package1. И есть доступ к переменной" i", который немного удивляет меня, так как он не соответствует утверждению "становится частным для любого кода вне подкласса"

Соседний класс после изменения:

package package1;

import package2.Child;

public class Neighbour {

    public void protectedTesting(){
        Child child = new Child();
        System.out.println(child.i); // access!
    }
}

, пожалуйста, прояснить это для меня. Спасибо.

4 6

4 ответа:

Короче говоря, protected является частным пакетом, а также видимым для подклассов. Даже JLS неясно об этом (JLS §6.6.2):

Член или конструктор объекта могут быть доступны извне пакета, в котором он объявлен только кодом, ответственным за реализацию этого объекта.

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

См. также:

И есть доступ к переменной" i", который немного удивляет меня, так как он не соответствует утверждению "становится частным для любого кода вне подкласса"

--> но вы переместили класс Neighbour в пакет package1, который соответствует "Protected members can be accessed by classes in same package"

" Как только подкласс-вне-пакета наследует защищенный элемент, этот элемент (как наследуется подклассом) становится частным для любого кода вне подкласса, за исключением подклассов из подкласса."

--> внутри пакета он по-прежнему защищен и не является частным для всех классов внутри пакета.

Истина не в "Sun Certified Java Programmer Study Guide", а в спецификации языка Java

6.6.2. Подробности о защищенном доступе

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

protected видимость включает видимость на уровне пакета. Наследование позволяет рассматривать объект Child как экземпляр объекта Parent. Поскольку член i Parent объявлен в том же пакете, он доступен из Neighbour.

package package1;

import package2.Child;

public class Neighbour {

    public void protectedTesting() {
        Parent neighboured = new Child();
        System.out.println(neighboured.i); // access
    }
}