04.10 Innere Klassen

Bis jetzt haben Sie immer neue Klassen in einer neuen Datei angelegt und kompiliert. Java bietet noch weitere Möglichkeiten: innere Klassen, sprich Klassen, die in einer anderen Klasse definiert sind. Die Vorteile/Einsatzorte/Möglichkeiten solcher Klassen liegen u. a hier:

Man unterscheidet zwischen mehreren Varianten:

Statische, geschachtelte Klassen

Statische, geschachtelte Klassen (static, nested classes) können direkt über die äußere Klasse angesprochen werden – sofern der Sichtbarkeitsmodifizierer dies zulässt. Dabei verhalten sie sich wie gewöhnliche Klassen. Es kann eine neue Instanz erstellt werden, der Zugriff auf Attribute und Methoden funktioniert wie gewohnt und auch auf statische Inhalte kann ohne Probleme zugegriffen werden. Eben wie eine ganz gewöhnliche Klasse. Zusätzlich kann eine statische, geschachtelte Klasse aber auch noch auf die statischen Attribute und Methoden der äußeren Klasse zugreifen. Objektattribute und Objektmethoden sind hingegen tabu.

Die static, nested class wird wie folgt erstellt:

public class AClass {
  public static class StaticNestedClass {
    ...
  }
}

Ein konkreteres Beispiel:

package de.inner;
public class StaticNestedTest {

  private static int id = 23;
  
  private static void printNestedStaticId () {
    System.out.println("Outer, Static Method: " + StaticNested.id);
  }

  public void callStaticNestedClassMethod() {
    StaticNested.printId();
  }
  
  public static class StaticNested {
  
  private static int id = 42;  
  
    public StaticNested() {
      System.out.println("Object created!");
    }
    
    public static void printOuterIDStatic() {
      System.out.println("Nested, Static Method: " + StaticNestedTest.id);
    }
  
    private static void printId() {
      System.out.println("Nested, Static Method: " + StaticNested.id);
    }
    
    public void callOuterMethod() {
      StaticNestedTest.printNestedStaticId();
    }
  }
  
  public static void main(String[] args) {
    
    StaticNestedTest.StaticNested.printOuterIDStatic();
    StaticNestedTest.StaticNested sn = new StaticNestedTest.StaticNested();
    sn.callOuterMethod();
    StaticNestedTest snt = new StaticNestedTest();
    snt.callStaticNestedClassMethod();
  }
}

Selbstverständlich kann auch die äußere Klasse auf die statische, verschachtelte Klasse zugreifen und so z. B. Methoden der statischen, verschachtelten Klasse aufrufen. Hierfür verwenden Sie StatischeVerschachtelteKlasse.attribut/methode

Innere Klassen

Innere Klassen (inner classes) sind im Prinzip nicht statische, verschachtelte Klassen. Sie unterscheiden sich in folgenden Punkten von statischen, verschachtelten Klassen:

  1. Keine statischen Attribute oder Methoden
  2. Zugriff erfolgt nicht über die äußere Klasse, sondern ein Objekt der äußeren Klasse
  3. Zugriff auf Objektattribute und Objektmethoden, kein Zugriff auf Klassenattribute und Klassenmethoden
  4. Die innere Klasse muss immer über new instanziiert werden

Um eine innere Klasse zu erstellen, gehen Sie wie folgt vor:

public class AClass {
  public class InnerClass {
    ...
  }
}

Ein konkreteres Beispiel:

package de.inner;
public class InnerTest {

  private int objID = 23;
	
  public class Inner {
		
    private int objID = 42;
	
    public void printOutID() {
      System.out.println("Out ObjID from In: " + InnerTest.this.objID);
    }
		
    public void printInnerID() {
      System.out.println("In ObjID from In: " + Inner.this.objID);
    }
  }
	
  public void printInnerObjID(Inner in) {
    System.out.println("In ObjID from Out: " + in.objID);
  }
	
  public static void main(String[] args) {
		
    InnerTest out = new InnerTest();
    InnerTest.Inner in = out.new Inner();
    in.printInnerID();
    in.printOutID();
    out.printInnerObjID(in);
  }
}

Um in der inneren Klasse bei gleichnamigen Attributen bzw. Methoden besser unterscheiden zu können, ob auf die Attribute bzw. Methoden der äußeren oder die der inneren Klasse zugegriffen werden soll, verwenden Sie die Schreibweise Klassenname.this.attribut/methode.

Lesen Sie auf der nächsten Seite etwas über lokale und anonyme Klassen, sowie der Ausgabe von inneren Klassen durch den Compiler.

4 Replies to “04.10 Innere Klassen”

  1. N/A

    Begriffsverwirrung!
    Inner Classes sind niemals static. Statische Nested Classes sind Member-Classes.
    Siehe JLS Kapitel 8

  2. Stefan Kiesel

    Hallo,

    danke für den Hinweis! Da ist wohl versehentlich eine veraltete Version des Kapitels veröffentlicht worden. Ursprünglich waren die Begrifflichkeiten so gewählt, dass sich „irgendwie“ alles auf den Titel des Kapitels (INNERE Klassen) bezieht. Davon bin ich aber mittlerweile abgewichen. Ich werde das umgehend ausbessern.

    Gruß

  3. Gast

    Hallo Stefan,

    geht es bei der Äußerung:

    „Inner Classes sind niemals static. Statische Nested Classes sind Member-Classes.“

    lediglich um die korrekte Begrifflichkeit ?

    Ich habe soeben das folgende Beispiel geschrieben:

    ————————-

    public class KlasseAussen {
    	public static int v1 = 42;	
    	public KlasseAussen() {		
    		InnerClass inner = new InnerClass();
    		System.out.println(inner.v2); // Zugriff nur per Referenz !
    	}	
    	// Innere statische Klasse !   <------------- Falsche Bezeichnung ?! 
    	public static class InnerClass {		
    		public static int v2 = 24;		
    		public InnerClass() {
    			System.out.println(v1);
    		}
    	}	
    	public static void main(String[] args) {
    		KlasseAussen inner = new KlasseAussen();
    	}	
    }

    ————————-

    Ich würde die innere Klasse mit der Bezeichnung ‚InnerClass‘ als statische innere Klasse bezeichnen.

    Sofern ich die Äußerung richtig verstanden haben sollte, wird das was ich als ’statische innere Klasse ‚ bezeichne, als ‚Member-Class oder Nested Classes‘ bezeichnet.
    Die Bezeichnung ’statische innere Klasse ‚ wäre falsch und es gäbe nur eine ’nicht statische innere Klasse‘.

    Korrekt ?

  4. Stefan Kiesel

    Hallo Gast,

    ja, dabei geht es lediglich um die korrekten Begrifflichkeiten, die im Kapitel aber bereits korrigiert wurden.

    Ihre statische, innere Klasse wird als „nested, static class“ oder zu deutsch „geschachtelte, statische Klasse“ bezeichnet. Wenn Sie aber zu jemanden „statische, innere Klasse“ sagen, wird dieser Sie auch ohne Probleme verstehen.

    Eine innere Klasse ist eine Klasse in einer anderen Klasse ohne das Schlüsselwort static. Im Vergleich zu Objektattributen und Klasssenattribute könnte man eine Innere Klasse als Objektklasse und eine static, nested Klasse als Klassenklasse bezeichnen.

    Ich hoffe Ihnen ist nun alles soweit klar. Falls nicht, einfach nachfragen 🙂 .

    Gruß
    Stefan

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.