Innere Klassen Innere Klassen Lernziele: innere Klassen, statische geschachtelte Klassen, anonyme Klassen. Literatur: Java Tutorial & Arnold, K., Gosling, J. und Holmes,D... Page 1
Innere Klassen Der erste Eindruck in Java: alle Klassen sind "top level", gewöhnlich Eine pro Datei Klassen können jedoch innerhalb anderer Klassen deklariert werden. Warum: meist wenn eine Klasse nur innerhalb einer Anderen benötigt wird. Beispiel: verkettete Liste doppelt verkettete Liste: zwei Klassen ListenKnoten : enthält Daten und Pointer zum nächsten und vorherigen Knoten VerketteteListe : Pointer zu Kopf und Ende der Liste ListenKnoten ist Hilfsklasse und wird nur von VerketteteListe genutzt. VerketteteListe ListenKnoten Listenknoten ListenKnoten ListenKnoten Kopf 1 2 3 4 Ende Page 2
Innere Klasse public class LinkedList {... // inner class private class ListCell { int value; ListCell next; ListCell previous; // end ListCell private ListCell head; private ListCell tail;... // end LinkedList LinkedList Methoden können ListCell Objekte erzeugen und nutzen. Nutzer von ausserhalb der LinkedList können die ListCell Klasse nicht sehen Implementierungs Detail Innere Klasse kennt äussere Variablen public class OuterClassDemo { private int a; public InnerClass subobject; public class InnerClass { public int b; public int sum() { return a + b; // end sum // end class InnerClass // constructor Innere Klasse hat Referenz auf das a der äusseren Klasse. public OuterClassDemo( int aval, int bval) { a = aval; subobject = new InnerClass(); subobject. b = bval; // end constructor public static void main( String args[]) { OuterClassDemo tester = new OuterClassDemo( 7, 5); tester. a = 4; tester. subobject. b = 3; // end main // end class OuterclassDemo Page 3
Grenzen der Inneren Klassen public class OuterClass {... public InnerClass subobject; public class InnerClass { public int b;... // end class InnerClass // end class OuterClass Ein äusserer Nutzer kann ein inneres Objekt referenzieren. OuterClass x = new OuterClass(); int y = x.subobject.b; Ein äusserer Nutzer kann KEINE Instanz eines inneren Objekts erzeugen. InnerClass y = new OuterClass.InnerClass(); // illegal Objekte 'Innerer Klassen' können nur innerhalb der äusseren Klasse existieren. Implementierungsdetails Unsere geistige Vorstellung von den Objekten: a: 13 subobject b: 7 Wie es in Java implementiert ist: a: 13 subobject b: 7 pointer vom inneren Objekt zum äusseren Objekt Page 4
Statische geschachtelte Klassen public class OuterClass { statische geschachtelte Klassen verhalten sich wie private int a; externe isolierte Klassen. public InnerClass subobject; public static class InnerClass { Nur der Zugriff erfolgt über OuterName.innerName public int b; public int sum() { Referenz zu `Member`-Variablen der return a + b; äusseren Klasse ist unzulässig. // end sum // end class InnerClass... Pointer vom `inneren Objekt zum äusseren Objekt existiert nicht! public static void main( String args[]) { OuterClass tester = new OuterClass( 7, 5); tester. a = 4; tester. subobject. b = 3; // end main Wozu statische geschachtelte Klassen? Eine Klasse innerhalb der anderen zu definieren spiegelt ihre Beziehung wieder. Wird oft bei Exceptions verwendet. public class MyClass { // data and methods for MyClass // MyClass may raise exceptions public static class MyException {.. // end MyClass MyException-Object muss nicht unbedingt Teil von MyClass sein, es könnte auch durch eine Methode in MyClass erzeugt werden. Page 5
Anonyme Klassen: Motivation Angenommen wir wünschen eine kleine Veränderung einer Klasse. Beispiel: ein Stack der automatisch `Debug -Information ausgibt. 1. Lösung: erweitere eine Stackimplementierung. class DebugStack extends SuperStack { public void push(int i) { super.push(i); System.out.println("just put " + i); public int pop() { int result = super.pop(); System.out.println("just got" + result); return result; Anonyme Klassen Was aber wenn wir nur eine einzige Instanz des Objekts benötigen. Dann kann eine Anonyme Klasse verwendet werden. Stack mystack = new Stack { public void push(int i) { super.push(i); System.out.println("just put " + i); public int pop() { int result = super.pop(); System.out.println("just got " + result); return result; ; Anonyme Klassen sind nur nützlich wenn es darum geht Methoden zu erweitern und nicht um Neue zu schaffen. Page 6
Anonyme Klassen & Interfaces Anonyme Klassen können verwendet werden, wenn Objekte erzeugt werden sollen, die ein Interface implementieren. Stack mystack = new Stack() { public void push(int i) {... public int pop() {... boolean isempty() {... ; Page 7