Подтвердить что ты не робот

Переопределение защищенных методов в Java

Test.java

package a;
import b.B;
public class Test {
    public static void main(String[] v) {
        new A().test();
        new B().test();
    }
}

A.java:

package a;
public class A {
    protected void test() { }
}

B.java:

package b;
public class B extends a.A {
    protected void test() { }
}

Почему new B().test() дает ошибку? Не нарушают ли правила видимости?

B.test() невидим в Test, потому что они находятся в разных пакетах, и все же он отказывается вызывать видимый test() в B суперклассе.

Приветствуются ссылки на соответствующую часть JLS.

4b9b3361

Ответ 1

Здесь вы переходите к JLS в ключе protected: JLS protected description и JLS protected example.

В основном модификатор protected означает, что вы можете получить доступ к полю/методу/... 1) в подклассе данного класса и 2) из ​​классов в том же пакете.

Из-за 2) new A().test() работает. Но new B().test() не работает, потому что класс B находится в другом пакете.

Ответ 2

Это не так, как наследование работает на Java.

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

Кажется, вы ожидаете, что Java автоматически вернется к методу суперкласса, но этого не произойдет.

Я попытаюсь выкопать JLS позже, почему это не сделано...

Ответ 3

Проблема заключается в том, что во время компиляции вы сообщаете Java, что хотите получить доступ к защищенному члену класса, когда у вас нет такого доступа.

Если вы это сделали,

  A a = new B();
  a.test();

Затем он будет работать, и переопределенный метод будет запущен, потому что во время компиляции Java проверяет, что у вас есть доступ к A. Во время выполнения предоставленный объект имеет соответствующий метод, поэтому выполняется метод B(). Динамическое связывание или поздняя привязка - это ключ.

Ответ 4

Да, возможно переопределение защищенного метода.

class A{
protected void f(){
SOP("A");
}}
class B extends A{
protected void f(){
SOP("B");
}
public static void main(String...args)
{
B b=new B();
b.f();
}
}

Выход: B