Модификатор на достъп, защитен от Java

1. Общ преглед

В езика за програмиране Java полетата, конструкторите, методите и класовете могат да бъдат маркирани с модификатори на достъпа. В този урок ще разгледаме защитения достъп.

2. Защитената ключова дума

Докато елементите, декларирани като частни, могат да бъдат достъпни само от класа, в който са декларирани, защитената ключова дума позволява достъп от подкласове и членове на същия пакет.

Използвайки защитената ключова дума, ние вземаме решения за това кои методи и полета трябва да се считат за вътрешни елементи на йерархията на пакет или клас и кои са изложени на външен код.

3. Деклариране на защитени полета, методи и конструктори

Първо, нека създадем aклас с име FirstClass, съдържащ защитено поле, метод и конструктор:

public class FirstClass { protected String name; protected FirstClass(String name) { this.name = name; } protected String getName() { return name; } }

С този пример, като използваме защитената ключова дума, предоставихме достъп до тези полета на класове в същия пакет като FirstClass и на подкласове на FirstClass .

4. Достъп до защитени полета, методи и конструктори

4.1 От същия пакет

Сега нека видим как можем да осъществим достъп до защитени полета, като създадем нов GenericClass, деклариран в същия пакет като FirstClass :

public class GenericClass { public static void main(String[] args) { FirstClass first = new FirstClass("random name"); System.out.println("FirstClass name is " + first.getName()); first.name = "new name"; } }

Тъй като този извикващ клас е в същия пакет като FirstClass, е позволено да вижда и да взаимодейства с всички защитени полета, методи и конструктори.

4.2. От различен пакет

Нека сега се опитаме да взаимодействаме с тези полета от клас, деклариран в различен пакет от FirstClass :

public class SecondGenericClass { public static void main(String[] args) { FirstClass first = new FirstClass("random name"); System.out.println("FirstClass name is "+ first.getName()); first.name = "new name"; } }

Както виждаме, получаваме грешки при компилация :

The constructor FirstClass(String) is not visible The method getName() from the type FirstClass is not visible The field FirstClass.name is not visible

Точно това очаквахме, използвайки защитената ключова дума. Това е така, защото SecondGenericClass не е в същия пакет като FirstClass и не го подкласира.

4.3 От подклас

Нека сега видим какво се случва, когато декларираме клас, разширяващ FirstClass, но деклариран в различен пакет :

public class SecondClass extends FirstClass { public SecondClass(String name) { super(name); System.out.println("SecondClass name is " + this.getName()); this.name = "new name"; } }

Както се очаква, можем да осъществим достъп до всички защитени полета, методи и конструктори. Това е така, защото SecondClass е подклас на FirstClass .

5. защитен вътрешен клас

В предишните примери видяхме защитени полета, методи и конструктори в действие. Има още един частен случай - защитен вътрешен клас.

Нека създадем този празен вътрешен клас в нашия FirstClass :

package com.baeldung.core.modifiers; public class FirstClass { // ... protected static class InnerClass { } }

Както виждаме, това е статичен вътрешен клас и може да бъде конструиран извън екземпляр на FirstClass . Тъй като обаче е защитен , можем да го създадем само от код в същия пакет като FirstClass .

5.1 От същия пакет

За да тестваме това, нека редактираме нашия GenericClass :

public class GenericClass { public static void main(String[] args) { // ... FirstClass.InnerClass innerClass = new FirstClass.InnerClass(); } }

Както виждаме, можем да създадем екземпляр на InnerClass без никакъв проблем, защото GenericClass е в същия пакет като FirstClass .

5.2. От различен пакет

Нека се опитаме да създадем InnerClass от нашия SecondGenericClass, който, както си спомняме, е извън пакета на FirstClass :

public class SecondGenericClass { public static void main(String[] args) { // ... FirstClass.InnerClass innerClass = new FirstClass.InnerClass(); } }

Както се очаква, получаваме грешка при компилация :

The type FirstClass.InnerClass is not visible

5.3. От подклас

Нека се опитаме да направим същото от нашия SecondClass :

public class SecondClass extends FirstClass { public SecondClass(String name) { // ... FirstClass.InnerClass innerClass = new FirstClass.InnerClass(); } }

Очаквахме да създадем инстанция за нашия InnerClass с лекота. Тук обаче получаваме грешка при компилацията:

The constructor FirstClass.InnerClass() is not visible

Нека да разгледаме нашата декларация InnerClass :

protected static class InnerClass { }

The main reason we are getting this error is that the default constructor of a protected class is implicitly protected. In addition, SecondClassis a sub-class of FirstClass but is not a sub-class of InnerClass. Finally, we also declaredSecondClass outside FirstClass' package.

For all these reasons, SecondClass can't access the protectedInnerClass constructor.

Ако искахме да разрешим този проблем и да позволим на SecondClass да създаде екземпляр на обект InnerClass , бихме могли изрично да декларираме публичен конструктор :

protected static class InnerClass { public InnerClass() { } }

Правейки това, вече не получаваме грешка при компилация и вече можем да създадем екземпляр на InnerClass от SecondClass .

6. Заключение

В този бърз урок обсъдихме модификатора на защитения достъп в Java. С него можем да гарантираме излагането само на необходимите данни и методи на подкласове и класове в същия пакет.

Както винаги, примерният код е достъпен в GitHub.