Zugriffsbeschränkungen in Java
private package protected public
selbe Klasse x x x x
selbes Paket x x x
Unterklasse x x
Überall x
Beim Fehlen einer Angabe ("default"):
- bei einem Klasseneintrag: package
- bei einem Schnittstelleneintrag: public
Invarianten einer Klasse
Beispiel: Guthaben bei Konto soll nicht negativ sein.
Zugriffsmodifikatoren bei Feldern
private
Normalerweise werden Felder mit »private« gekennzeichnet, damit die Klasse ihre Invarianten wahren kann.
public
Ein »public«-Feld könnte zur Vereinfachung der Programmierung in kleinen Programmen verwendet werden. Es könnte bei Klassen verwendet werden, die keine mit diesem Feld verbundenen Invarianten haben.
Zugriffsmodifikatoren bei Methoden
public
Wenn eine Methode einen Deskriptor einer Schnittstelle implementieren soll, muß sie mit »public« gekennzeichnet werden, ansonsten kann »public« auch weggelassen werden, sollte aber grundsätzlich verwendet werden, um Methoden zu kennzeichnen, die auch für den Aufruf aus anderen Klassen gedacht sind.
(Der Deskriptor einer Methode ist die Kombination aus dem Aufruftyp dieser Methode und der Signatur dieser Methode. Die Signatur einer Methode ist die Kombination aus dem Methodenbezeichner dieser Methode und der eingeklammerten Parameterliste dieser Methode.)
private
Wurde eine Methode mit dem Methodenmodifizierer "private" deklariert, so kann sie nur von anderen Methoden ihrer Klasse aufgerufen werden. Sie ist sozusagen nach außen hin „versteckt“.
Zugriffsmodifikatoren bei Klassen
Wenn mehrere Klassen in einer Quelldatei deklariert werden, dann darf höchstens eine davon public sein, der Name der Quelldatei wird dann mit dem Namen dieser Klasse gebildet.
Der Zugriffsmodifikator »private« darf bei Klassen, die nicht in anderen Deklarationen enthalten sind, nicht verwendet werden.
Ein Konto mit einem Feld "wert" soll implementiert werden.
Das Feld "wert" soll am Anfang des Programmes auf den Wert "0" gesetzt werden.
Die Operation "einzahlen( betrag )" wird durch Addition des Betrags "betrag" zum Feld "wert" implementiert.
Die Operation "saldo( betrag )" wird durch Rückgabe des Wertes des Felds "wert" implementiert.
Main.java
class Konto
{ private static int wert;
public static void einzahlen( final int betrag )
{ wert = wert + betrag; }
public static int saldo(){ return wert; }}
public final class Main
{ public static void main( final java.lang.String[] args )
{ Konto.einzahlen( 1500 ); Konto.einzahlen( 7600 );
java.lang.System.out.println( Konto.saldo() ); }}System.out
9100
Private Konstruktoren
In manchen Fällen kann es sinnvoll sein, die Erzeugung von Exemplaren einer Klasse zu verhindern. Beispielsweise weil die Klasse nur als ein Behälter statischer Klassenmethoden dienen soll. Zu diesem Zweck kann ein privater parameterloser Konstruktor definiert werden—Exemplare können dann nicht in Methoden außerhalb dieser Klasse erzeugt werden.
Main.java
class Main
{ public static void main( final java.lang.String[] args )
{ final MyClass m = new MyClass(); }}
class MyClass{ private MyClass(){} }Konsole
javac PrivateConstructor.java
PrivateConstructor.java:3: MyClass() has private access in MyClass
{ final MyClass m = new MyClass(); }}
^
Beispiel
Jemand fragte nach Objekten, die alle einen individuellen Zähler enthalten.
class globalCounter
{ private static int value = 0;
public static int getValue(){ return value++; }}
class Identifier
{ final private java.lang.String prefix;
private int count;
public Identifier()
{ this.prefix = java.lang.String.valueOf( globalCounter.getValue() );
this.count = 0; }
public java.lang.String get()
{ return prefix + "-" + java.lang.String.valueOf( count++ ); }}
public final class Main
{ final static java.lang.String lineSeparator =
java.lang.System.getProperty( "line.separator" );public static void main( final java.lang.String[] args )
{ final Identifier identifier0 = new Identifier();
final Identifier identifier1 = new Identifier();java.lang.System.out.println
( identifier0.get() + lineSeparator +
identifier0.get() + lineSeparator +
identifier0.get() + lineSeparator +
identifier1.get() + lineSeparator +
identifier1.get() + lineSeparator +
identifier1.get() + lineSeparator ); }}
0-0
0-1
0-2
1-0
1-1
1-2