Глубокое понимание защищенного модификатора в Java

Java задняя часть переводчик

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

В Java модификатор доступа является самым базовым знанием, а модификатор protected — лишь одним из них.Если вы хотите спросить, почему бы не взять public, default и private для более глубокого изучения? Тогда, прочитав эту статью, вы поймете, почему стоит задуматься о защищенном.

В «Размышлениях на Java» название protected — это «унаследованные права доступа», которые мы помним как protected: protected должен иметь отношения наследования, чтобы иметь возможность доступа. Итак, вы думаете, что понимаете, но действительно ли вы понимаете это предложение?

Сначала рассмотрим несколько вопросов:

  1. В том же пакете могут ли объекты подкласса обращаться к защищенным методам суперкласса?

  2. Можно ли в разных пакетах создать объект подкласса в подклассе для доступа к защищенному методу суперкласса?

  3. Можно ли в разных пакетах создать объект родительского класса в подклассе для доступа к защищенному методу родительского класса?

  4. Могут ли объекты, созданные в подклассе другого подкласса, в разных пакетах обращаться к защищенным методам общедоступного суперкласса?

  5. А как насчет защищенного метода родительского класса с модификатором static?

В "Thinking in Java" есть предложение: "protected также предоставляет права доступа к пакету, то есть другие классы в том же пакете могут получить доступ к protected элементам", на самом деле модификатор protected содержит разрешения модификатора по умолчанию, поэтому первый 1 вопрос, на который вы уже знаете ответ, в том же пакете обычный класс или подкласс может получить доступ к защищенному методу базового класса.

Родительский класс является нестатическим защищенным декорированным классом.

package com.protectedaccess.parentpackage;

public class Parent {

    protected String protect = "protect field";

    protected void getMessage(){
        System.out.println("i am parent");
    }
}

В разных пакетах к защищенному методу нельзя получить доступ через ссылку на родительский класс в подклассе.

Независимо от того, создаете ли вы объект Parent или создаете объект Son1 с помощью полиморфизма, пока ссылка Parent недоступна, компилятор выдаст сообщение об ошибке.

package com.protectedaccess.parentpackage.sonpackage1;

import com.protectedaccess.parentpackage.Parent;

public class Son1 extends Parent{
    public static void main(String[] args) {
        Parent parent1 = new Parent();
        // parent1.getMessage();   错误

        Parent parent2 = new Son1();
        // parent2.getMessage();  错误
    }
}

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

Подкласс фактически наследует метод родительского класса, доступ к которому можно получить через объект подкласса, или непосредственно в методе подкласса, а также может вызвать метод в родительском классе через ключевое слово super.

package com.protectedaccess.parentpackage.sonpackage1;

import com.protectedaccess.parentpackage.Parent;

public class Son1 extends Parent{
    public static void main(String[] args) {
        Son1 son1 = new Son1();
        son1.getMessage(); // 输出:i am parent,
    }
    private void message(){
        getMessage();  // 如果子类重写了该方法, 则输出重写方法中的内容
        super.getMessage(); // 输出父类该方法中的内容
    }
}

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

package com.protectedaccess.parentpackage.sonpackage2;

import com.protectedaccess.parentpackage.Parent;

public class Son2 extends Parent {

}

Обратите внимание, что Son2 — это еще один подкласс, и объект, созданный в Son1, не может получить доступ к защищенному методу родительского класса.

package com.protectedaccess.parentpackage.sonpackage1;

import com.protectedaccess.parentpackage.Parent;
import com.protectedaccess.parentpackage.sonpackage2.Son2;

public class Son1 extends Parent{
    public static void main(String[] args) {
        Son2 son2 = new Son2();
        // son2.getMessage(); 错误
    }
}

Родительский класс является статическим защищенным оформленным классом.

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

package com.protectedaccess.parentpackage;

public class Parent {

    protected String protect = "protect field";

    protected static void getMessage(){
        System.out.println("i am parent");
    }
}

Доступ к статическим методам осуществляется непосредственно по имени класса.

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

package com.protectedaccess.parentpackage.sonpackage1;

import com.protectedaccess.parentpackage.Parent;

public class Son3 extends Parent{
    public static void main(String[] args) {
        Parent.getMessage(); // 输出: i am parent
    }
}

Недоступно для не-подклассов в разных пакетах

package com.protectedaccess.parentpackage.sonpackage1;

import com.protectedaccess.parentpackage.Parent;

public class Son4{
    public static void main(String[] args) {
       // Parent.getMessage(); 错误
    }
}

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