Возможно ли в Java вызывать защищенный метод из другого не дочернего класса без использования отражения? - PullRequest
0 голосов
/ 04 июля 2019

У меня есть фрагмент кода:

abstract class Foo {
    protected abstract void method(String o);

    public void method(Object o) {
        System.out.println("method(Object)");
    }
}

class Bar extends Foo {
    protected void method(String key) {
        System.out.println("method(String)");
    }
}

public class OverloadingTest {

    public static void main(String[] args) {
        Bar bar = new Bar();
        bar.method("hello");
        bar.method(null);
    }
}

который, к моему удивлению, печатает

method(String)
method(String)

на stdout, я хотел бы понять, как это возможно, поскольку метод, принимающий аргумент String (который вызывается), является защищенным методом, и его нельзя вызывать из класс, который не является, не расширяет Foo, вместо этого должен быть вызван открытый метод, который принимает Object, но это не так.

1 Ответ

0 голосов
/ 04 июля 2019

Да, любой код в том же пакете, что и Bar, может получить доступ к его защищенным методам.

Если бы вы переместили OverloadingTest в новый пакет - т.е. переместите его в файл в другой папке в вашем исходном дереве - тогда будет видна только подпись Foo#method(Object).

Защищенная видимость - это более упрощенная версия видимости по умолчанию для закрытого пакета AKA. Единственное различие между ними заключается в том, что защищенная видимость позволяет подклассу получать доступ к члену, даже если он находится в другом пакете.

Цитируя Документы Oracle по этому вопросу:

Защищенный модификатор указывает, что доступ к члену возможен только в его собственном пакете (как в случае с package-private) и, кроме того, подклассом его класса в другом пакете.

...