Переопределение защищенных методов в Java - PullRequest
13 голосов
/ 12 апреля 2011

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.

Ответы [ 4 ]

12 голосов
/ 12 апреля 2011

Вот вам ключевое слово JLS для protected ключевого слова: Описание защищенного JLS и Пример защищенного JLS .

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

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

7 голосов
/ 12 апреля 2011

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

Если вы сделали это вместо этого;

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

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

7 голосов
/ 12 апреля 2011

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

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

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

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

0 голосов
/ 15 августа 2015

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

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

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