Java ‘beschermde’ toegangsmodificator

1. Overzicht

In de programmeertaal Java kunnen velden, constructors, methoden en klassen worden gemarkeerd met toegangsmodificatoren. In deze tutorial zullen we kijken naar beschermd toegang.

2. Het beschermd Trefwoord

Terwijl elementen zijn gedeclareerd als privaat is alleen toegankelijk voor de klasse waarin ze zijn gedeclareerd, de beschermd trefwoord geeft toegang vanuit subklassen en leden van hetzelfde pakket.

Door de beschermd trefwoord, nemen we beslissingen over welke methoden en velden moeten worden beschouwd als interne onderdelen van een pakket of klassenhiërarchie, en die worden blootgesteld aan externe code.

3. Verklaren beschermd Velden, methoden en constructeurs

Laten we eerst eenklasse genoemd Eerste klas met een beschermd veld, methode en constructor:

openbare klasse FirstClass {beschermde tekenreeksnaam; beschermde FirstClass (String naam) {this.name = naam; } beschermde String getName () {retournaam; }}

Met dit voorbeeld, door de beschermd trefwoord, hebben we toegang tot deze velden verleend aan klassen in hetzelfde pakket als Eerste klas en naar subklassen van Eerste klas.

4. Toegang beschermd Velden, methoden en constructeurs

4.1 Uit hetzelfde pakket

Laten we nu eens kijken hoe we toegang kunnen krijgen beschermd velden door een nieuw GenericClass gedeclareerd in hetzelfde pakket als Eerste klas:

openbare klasse GenericClass {openbare statische leegte hoofd (String [] args) {FirstClass first = nieuwe FirstClass ("willekeurige naam"); System.out.println ("FirstClass naam is" + first.getName ()); first.name = "nieuwe naam"; }}

Omdat deze aanroepende klasse in hetzelfde pakket zit als Eerste klas, het is toegestaan ​​om alle beschermd velden, methoden en constructors.

4.2. Uit een ander pakket

Laten we nu proberen om met deze velden te communiceren vanuit een klasse die in een ander pakket is gedeclareerd dan Eerste klas:

openbare klasse SecondGenericClass {openbare statische leegte hoofd (String [] args) {FirstClass first = nieuwe FirstClass ("willekeurige naam"); System.out.println ("FirstClass naam is" + first.getName ()); first.name = "nieuwe naam"; }}

Zoals we kunnen zien, we krijgen compilatiefouten:

De constructor FirstClass (String) is niet zichtbaar De methode getName () van het type FirstClass is niet zichtbaar Het veld FirstClass.name is niet zichtbaar

Dat is precies wat we verwachtten door de beschermd trefwoord. Dit is zo omdat SecondGenericClass zit niet in hetzelfde pakket als Eerste klas en maakt er geen subklasse van.

4.3 Van een subklasse

Laten we nu kijken wat er gebeurt als we verklaren een klasse die zich uitbreidt Eerste klas maar gedeclareerd in een ander pakket:

public class SecondClass breidt FirstClass {public SecondClass (String name) {super (name) uit; System.out.println ("SecondClass-naam is" + this.getName ()); this.name = "nieuwe naam"; }}

Zoals verwacht hebben we toegang tot alle beschermde velden, methoden en constructors. Dit is zo omdat Tweede klas is een subklasse van Eerste klas.

5. beschermd Innerlijke klasse

In de vorige voorbeelden hebben we gezien beschermd velden, methoden en constructors in actie. Er is nog een specifiek geval - een beschermd innerlijke klasse.

Laten we deze lege innerlijke klasse creëren in ons Eerste klas:

pakket com.baeldung.core.modifiers; openbare klasse FirstClass {// ... beschermde statische klasse InnerClass {}}

Zoals we kunnen zien, is dit een statische innerlijke klasse en kan deze dus worden geconstrueerd van buiten een instantie van Eerste klas. Maar zoals het is beschermd, we kunnen het alleen instantiëren vanuit code in hetzelfde pakket als Eerste klas.

5.1 Uit hetzelfde pakket

Laten we om dit te testen onze GenericClass:

openbare klasse GenericClass {openbare statische leegte hoofd (String [] args) {// ... FirstClass.InnerClass innerClass = nieuwe FirstClass.InnerClass (); }}

Zoals we kunnen zien, kunnen we de InnerClass zonder enig probleem want GenericClass zit in hetzelfde pakket als Eerste klas.

5.2. Uit een ander pakket

Laten we proberen een InnerClass van onze SecondGenericClass die, zoals we ons herinneren, buiten is Eerste klas' pakket:

openbare klasse SecondGenericClass {openbare statische leegte hoofd (String [] args) {// ... FirstClass.InnerClass innerClass = nieuwe FirstClass.InnerClass (); }}

Zoals verwacht, we krijgen een compilatiefout:

Het type FirstClass.InnerClass is niet zichtbaar

5.3. Van een subklasse

Laten we proberen hetzelfde te doen vanuit de onze Tweede klas:

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

We verwachtten onze InnerClass met gemak. We krijgen hier echter ook een compilatiefout:

De constructor FirstClass.InnerClass () is niet zichtbaar

Laten we eens kijken naar onze InnerClass verklaring:

beschermde statische klasse InnerClass {}

De belangrijkste reden waarom we deze foutmelding krijgen, is dat de standaardconstructor van een beschermd klasse is impliciet beschermd. Daarnaast, Tweede klasis een subklasse van FirstClass maar is geen subklasse van InnerClass. Tenslotte, we hebben ook verklaardTweede klas buiten Eerste klas' pakket.

Voor al deze redenen, Tweede klas heeft geen toegang tot het beschermdInnerClass constructeur.

Als we wilden om dit probleem op te lossen en sta ons toe Tweede klas om een InnerClass voorwerp, we zouden expliciet een openbare constructeur kunnen verklaren:

beschermde statische klasse InnerClass {openbare InnerClass () {}}

Door dit te doen, krijgen we niet langer een compilatiefout en kunnen we nu een InnerClass van Tweede klas.

6. Conclusie

In deze korte tutorial hebben we de beschermd toegangsmodificator in Java. Hiermee kunnen we ervoor zorgen dat alleen de vereiste gegevens en methoden worden blootgesteld aan subklassen en klassen in hetzelfde pakket.

Zoals altijd is de voorbeeldcode beschikbaar op GitHub.