Java 'geschützter' Zugriffsmodifikator

1. Übersicht

In der Programmiersprache Java können Felder, Konstruktoren, Methoden und Klassen mit Zugriffsmodifikatoren markiert werden. In diesem Tutorial werden wir uns mit dem geschützten Zugriff befassen.

2. Das geschützte Schlüsselwort

Während auf Elemente, die als privat deklariert sind, nur von der Klasse zugegriffen werden kann, in der sie deklariert sind, ermöglicht das geschützte Schlüsselwort den Zugriff von Unterklassen und Mitgliedern desselben Pakets.

Mit dem geschützten Schlüsselwort treffen wir Entscheidungen darüber, welche Methoden und Felder als Interna eines Pakets oder einer Klassenhierarchie betrachtet werden sollen und welche externen Codes ausgesetzt sind.

3. Deklarieren geschützter Felder, Methoden und Konstruktoren

Zuerst erstellen wir eineKlasse mit dem Namen FirstClass, die ein geschütztes Feld, eine geschützte Methode und einen geschützten Konstruktor enthält:

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

In diesem Beispiel haben wir mithilfe des geschützten Schlüsselworts Klassen im selben Paket wie FirstClass und Unterklassen von FirstClass Zugriff auf diese Felder gewährt .

4. Zugriff auf geschützte Felder, Methoden und Konstruktoren

4.1 Aus demselben Paket

Lassen Sie uns nun sehen, wie wir auf geschützte Felder zugreifen können, indem wir eine neue GenericClass erstellen , die im selben Paket wie FirstClass deklariert ist :

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"; } }

Da sich diese aufrufende Klasse im selben Paket wie FirstClass befindet, können alle geschützten Felder, Methoden und Konstruktoren angezeigt und mit ihnen interagiert werden .

4.2. Aus einem anderen Paket

Versuchen wir nun, mit diesen Feldern aus einer Klasse zu interagieren, die in einem anderen Paket als FirstClass deklariert ist :

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"; } }

Wie wir sehen können, erhalten wir Kompilierungsfehler :

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

Genau das haben wir mit dem geschützten Schlüsselwort erwartet . Dies liegt daran, dass SecondGenericClass nicht im selben Paket wie FirstClass enthalten ist und es nicht in Unterklassen unterteilt.

4.3 Aus einer Unterklasse

Mal sehen, was passiert, wenn wir eine Klasse deklarieren , die FirstClass erweitert, aber in einem anderen Paket deklariert :

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

Wie erwartet können wir auf alle geschützten Felder, Methoden und Konstruktoren zugreifen. Dies liegt daran, dass SecondClass eine Unterklasse von FirstClass ist .

5. geschützte innere Klasse

In den vorherigen Beispielen haben wir geschützte Felder, Methoden und Konstruktoren in Aktion gesehen. Es gibt noch einen besonderen Fall - eine geschützte innere Klasse.

Erstellen wir diese leere innere Klasse in unserer FirstClass :

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

Wie wir sehen können, ist dies eine statische innere Klasse und kann daher von außerhalb einer Instanz von FirstClass erstellt werden . Da es jedoch geschützt ist , können wir es nur aus Code im selben Paket wie FirstClass instanziieren .

5.1 Aus demselben Paket

Um dies zu testen, bearbeiten wir unsere GenericClass :

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

Wie wir sehen können, können wir die InnerClass problemlos instanziieren , da sich GenericClass im selben Paket wie FirstClass befindet .

5.2. Aus einem anderen Paket

Versuchen wir, eine InnerClass aus unserer SecondGenericClass zu instanziieren, die sich, wie wir uns erinnern, außerhalb des FirstClass- Pakets befindet:

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

Wie erwartet erhalten wir einen Kompilierungsfehler :

The type FirstClass.InnerClass is not visible

5.3. Aus einer Unterklasse

Versuchen wir, dasselbe mit unserer SecondClass zu tun :

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

Wir hatten erwartet, unsere InnerClass mit Leichtigkeit zu instanziieren . Wir erhalten jedoch auch hier einen Kompilierungsfehler:

The constructor FirstClass.InnerClass() is not visible

Werfen wir einen Blick auf unsere InnerClass- Deklaration:

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.

Wenn wir dieses Problem lösen und unserer SecondClass erlauben möchten , ein InnerClass- Objekt zu instanziieren , könnten wir explizit einen öffentlichen Konstruktor deklarieren :

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

Auf diese Weise erhalten wir keinen Kompilierungsfehler mehr und können jetzt eine InnerClass von SecondClass instanziieren .

6. Fazit

In diesem kurzen Tutorial haben wir den Modifikator für geschützten Zugriff in Java erläutert . Damit können wir sicherstellen, dass nur die erforderlichen Daten und Methoden Unterklassen und Klassen im selben Paket zugänglich gemacht werden.

Wie immer ist der Beispielcode auf GitHub verfügbar.