Java защищенный доступ не работает - PullRequest
3 голосов
/ 02 декабря 2008

В Java есть три уровня доступа:

  • Public - Открытый миру
  • Частный - только для класса
  • Защищено - открыто только для класса и его подклассов (наследование).

Так почему же компилятор Java допускает это?

TestBlah.java:

public class TestBlah {

    public static void main(String[] args) {
        Blah a = new Blah("Blah");
        Bloo b = new Bloo("Bloo");
        System.out.println(a.getMessage());
        System.out.println(b.getMessage()); //Works
        System.out.println(a.testing);
        System.out.println(b.testing); //Works
    }
}

Blah.java:

public class Blah {
    protected String message;

    public Blah(String msg) {
        this.message = msg;
    }

    protected String getMessage(){
        return(this.message);
    }   
}

Bloo.java:

public class Bloo extends Blah {
    public Bloo(String testing) {
        super(testing);
    }
}

Ответы [ 5 ]

13 голосов
/ 02 декабря 2008

На самом деле это должно быть:

Открыть только для классов в одном пакете класс и его подклассы (наследование)

Вот почему

10 голосов
/ 02 декабря 2008

Потому что защищенный означает подкласс или других классов в том же пакете.

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

Таким образом, protected находится между значением по умолчанию и public доступом.

5 голосов
/ 02 декабря 2008

На самом деле существует четыре уровня доступа: «открытый», «защищенный», «закрытый» и по умолчанию, также известный как частный пакет или защищенный пакет. По умолчанию доступ к пакету ограничен. По умолчанию это очень полезно, и я часто его использую.

5 голосов
/ 02 декабря 2008

Чтобы быть более конкретным, вы ожидаете, что protected будет работать так же, как в C ++.

Однако в Java это имеет другое значение. В Java защищенный метод доступен классу (очевидно), всем остальным классам в том же пакете и любым подклассам этого класса. Классы в других пакетах не будут иметь доступа, если они не наследуют этот исходный класс.

См. Аналогичный вопрос для получения более подробной информации о маркерах наследования.

Лично я почти никогда не пользуюсь protected. Я разрабатываю приложения, а не фреймворки, поэтому я с большей вероятностью определяю public методы, private данные и довольно часто отмечаю весь свой класс как final.

3 голосов
/ 02 декабря 2008

Вы можете позвонить b.getMessage(), потому что b имеет тип Bloo, который расширяет Blah, а getMessage() защищен. Защищенный, как вы упомянули, позволяет подклассам получать доступ к методу.

Вы получили следующие ошибки:

  • Вызов super() без аргументов в конструкторе Bloo является ошибкой. Компилятор не может найти конструктор без параметров Blah, поскольку вы определили его с параметром String.
  • Вызов new Blah() в TestBlah main метод является ошибкой по той же причине, что и выше.
  • Ссылка на a.testing и b.testing является ошибкой, поскольку вы не определили переменную testing для какого-либо класса.
...