Java - помогите мне понять доступ к защищенным членам из подкласса (снова) - PullRequest
2 голосов
/ 23 ноября 2010

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

Вот класс A в упаковке PackOne

package PackOne;

public class A {

    protected void protectedMethod() {
        System.out.println("A's protectedMethod");
    }

}

Вот класс B в упаковке PackTwo. Однако это подкласс класса A.

package PackTwo;

import PackOne.A;

public class B extends A {

    public static void main(String[] args) {

        //Test 1 
        protectedMethod(); //error: non-static method protectedMethod()
                           // cannot be referenced from a static context.

        //Test 2
        A instanceofA = new A();
        instanceofA.protectedMethod();//error: protectedMethod() 
                                      //has protected access in PackOne.A
    }

    public void anotherMethodOfB() {

        //Test 3
        protectedMethod();//Pass 
    }

    //Test 4
    A instanceofA = new A();
    instanceofA.protectedMethod();//error: package instanceofA does not existed.
}

Пожалуйста, объясните, почему только вызов Test 3 в защищенном методе в классе A пройден, а остальные 3 теста (1,2,4) дают ошибки?

Ответы [ 5 ]

2 голосов
/ 23 ноября 2010

Это не имеет ничего общего с подклассами.

Нельзя вызывать нестатический метод из статической функции.Теперь

public static void main

является статическим, а

protectedMethod()

- нет.

Во-вторых, вы не можете вызывать защищенные методы «извне» класса.Если вы находитесь в классе B, вы не можете вызывать защищенный метод другого класса, кроме B.

Наконец, с пунктом 4 этот код не является частью метода, поэтому он не делает никакихсмысл вообще.

1 голос
/ 23 ноября 2010

Вам не так сложно понять protected доступ, как вам трудно понять , где вы можете вызывать методы экземпляра.

protectedMethod() - это метод, который выможет вызвать экземпляров класса A.

Первый вызов метода в main() недопустим, поскольку вы не пытаетесь вызвать метод в экземпляре A -main() - это статический метод, и поэтому он относится к классу из B, а не к экземпляру B.

Четвертый недопустим, поскольку вы не можете вызывать методыоператоры вне тела метода.

1 голос
/ 23 ноября 2010

Тест 1: Это не имеет ничего общего с защищенным / частным / общедоступным - вам нужен экземпляр объекта A для вызова этого метода.

Тест 2: вы НЕ находитесь в экземпляре объекта A или B, вы находитесь в статическом методе. Вы должны вызывать защищенный метод изнутри A или B - находясь в статическом методе не внутри класса, только количество экземпляров.

Тест 3: Вы находитесь в инстансе.

Тест 4: То же, что и Тест 2 - это анонимный статический метод.

0 голосов
/ 05 марта 2014

Чтобы понять вашу проблему, вам сначала нужно понять модификаторы доступа:

  • Public : любой класс может получить доступ к этой функции / переменной.(Вы все еще должны сначала создать экземпляр)
  • Private : Ни один другой класс не может получить доступ к этой функции / переменной.К нему можно получить доступ только внутри класса.Вы все еще можете использовать публичные функции из этого класса для доступа к его частным функциям и переменным, но прямой доступ невозможен.Обратите внимание, что частные функции и переменные НЕ наследуются (т.е. не являются частью подкласса).
  • Защищены : защищенные функции и переменные могут быть доступны только этому классу илюбой из его подклассов (любой класс, который прямо / косвенно наследует от него)

Static : позволяет вам вызывать функции без необходимости сначала создавать объект.Класс Math является хорошим примером, поскольку он содержит только статические методы и переменные (и даже не может быть создан).(примечание: Static не является модификатором доступа. Он также делает немного больше, чем просто это, посмотрите его, если хотите узнать больше)

Что касается вашего примера:

  1. Тест 1 : Ваш метод унаследован от класса A и, следовательно, доступен.Однако, поскольку это не статический метод, к нему нельзя получить прямой доступ: вам нужно либо сделать его статическим, либо создать экземпляр класса B, а затем вызвать функцию через этот экземпляр.
  2. Test2 : Это не работает, потому что A & B находятся в разных пакетах.Доступ к защищенным методам разрешен только в пределах одного пакета (даже если один наследуется от другого).Если A и B находятся в одном и том же пакете, это будет работать.
  3. Тест 3 : Объект B наследует открытые и защищенные методы A. Это не метод в A, которыйдоступ к нему, но унаследованный метод в B. Чтобы увидеть это, измените код A на следующий:

    <!-- language: java -->
    
    protected void protectedMethod() {
        System.out.println(getClass().getName() + ("'s Protected method"));
    }
    

    Выполнение этого даст в результате B's Protected method.

  4. Тест 4 : выполнение кода вне функции не работает.Не делайте этого (никогда).

Примечание: Вы можете получить доступ к закрытым и защищенным переменным с помощью отражения, хотя это гораздо более сложная вещь.Обычно это тоже не очень хорошая идея, поскольку переменные делаются частными / защищенными по какой-либо причине (например, для предотвращения несанкционированного доступа / изменений)

0 голосов
/ 23 ноября 2010
  • Метод protected в родительском классе позволяет подклассу использовать его для внутреннего использования , поэтому «Тест 3» проходит.
  • Тест 1 не пройден, поскольку main является статическим методом и не имеет доступа к нестатическим полям и функциям.
  • Тест 2 не пройден, потому что вы пытаетесь вызвать метод protected через экземпляр, что недопустимо.То же самое с тестом 4.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...