Вопрос

У меня только что есть странная ошибка, которая включает в себя защищенный модификатор.

У меня есть следующий код:

package p1;

public class C1 {
    protected void doIt() {}
}


package p2;

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        c1_instance.doIt(); // wtf!!!!
    }
}

Я получаю ошибку, заявляя, что doIt() Защищенный доступ и не может быть доступен! Но я нахожусь в подклассном классе и имею и доступ к doIt() метод

Разве это не ошибка?

Это было полезно?

Решение

У меня также было впечатление, что protected означал «доступный из того же пакета или из подкласса», но Язычная спецификация Конечно, более точнее и объясняет, что в подклассе S, «если доступ к квалифицированному имени Q.ID, где Q является именем выражения, то доступ разрешен тогда и только тогда, когда тип выражения Q S или подкласс S. "

Таким образом, вы можете только получить доступ к protected Метод суперкласса посредством ссылки на подкласс, из которого вы звоните, например:

public class C2 extends C1 {
    private C2 c2_other_instance;
    public void doItAgain() {
        c2_other_instance.doIt();
    }
}

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

Другие советы

В Java вы не можете позвонить protected методы В другом случае базового класса, даже из подкласса:

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        doIt();             // fine
        c1_instance.doIt(); // disallowed
    }
}

Единственное исключение - это когда базовый класс и подкласс находятся в одном пакете.

To quote the Java OO Учебное пособие:

А protected Модификатор указывает, что к участнику можно получить доступ только в своем собственном пакете (как в случае с Package Provate) и, кроме того, подклассом своего класса в другом пакете.

Защитный эквивалентен доступу к уровню упаковки; Вы не можете получить доступ к методу, если вы находитесь в другом пакете.

Вы должны иметь возможность вызвать doit () непосредственно, не проходя через объект C1_Instance, так как C2 является подклассом.

Из http://download.oracle.com/javase/tutorial/java/javaoo/accesscontrol.html

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

C2 может быть подкладом C1, но это не означает, что он может получить доступ к этим методам в другом случае, то есть C1_Instance не может быть экземпляром C2. Вы можете получить доступ к нему, если бы он был в том же пакете.

Нет, protected обеспечивает доступ в той же пакете и в уроках потомков. Вы не находитесь ни в одном и том же пакете, и не обращаетесь к нему непосредственно из урока потомков. C2 Потомок, но c1_instance не.

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

Теперь вот вопрос, почему есть ошибка, несмотря на доступ к этому защищенному участнику из его подкласса. Ответ состоит в том, чтобы получить доступ к защищенному методу из подкласса, который ваш подкласс должен использовать метод непосредственно из прямого подкласса. Здесь прямой подкласс - C2, но экземпляр C1_Instance нет. Вы можете использовать этот метод напрямую (doit () вместо c1_instance.doit ())

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top