Programmieren 2 – Java Überblick 1 2 3 4 5 6 7 8 9 10 11 Klassen und Objekte Vererbung Schnittstellen Innere Klassen Exceptions Funktionsbibliothek Datenstrukturen und Algorithmen Ein-/Ausgabe Graphische Benutzeroberflächen Applets Internet-Anwendungen © Prof. Dr. Björn Dreher Programmieren 2 - Java 144 Programmieren 2 – Java Überblick: 4. Innere Klassen 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Einleitung Geschachtelte statische Klassen Elementklassen Lokale Klassen Anonyme innere Klassen Beispiele Pakete © Prof. Dr. Björn Dreher Programmieren 2 - Java 145 1 4 Innere Klassen 4.1 Einleitung Organisation bisheriger Klassen Pro Klasse eine Datei Sog. Top-Level Klassen Hier: Klasse in einer Klasse: class Außen { class Innen { ... } ... } Innen ist eine „innere Klasse“ 4 Varianten: Geschachtelte statische Klassen Elementklassen Lokale Klassen Anonyme innere Klassen © Prof. Dr. Björn Dreher Programmieren 2 - Java 146 Programmieren 2 – Java Überblick: 4. Innere Klassen 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Einleitung Geschachtelte statische Klassen Elementklassen Lokale Klassen Anonyme innere Klassen Beispiele Pakete © Prof. Dr. Björn Dreher Programmieren 2 - Java 147 2 4 Innere Klassen 4.2 Geschachtelte statische Klassen Auch: Geschachtelte Top-Level Klassen und Schnittstellen Nested top-level class Statische Eigenschaft der Klasse public class Lampe { static String s = "Hell"; int i = 1; static class Birne { void leuchte() { System.out.println( s ); System.out.println( i ); // Fehler } } } Statische innere Klasse hat nur Zugriff auf statische Eigenschaften der äußeren Klasse Zugriff auf normale Attribute ist nicht möglich © Prof. Dr. Björn Dreher Programmieren 2 - Java 148 4 Innere Klassen 4.2 Geschachtelte statische Klasse Weitere Eigenschaften Name der inneren Klasse muss von dem der äußeren Klasse verschieden sein Innere Klasse hat Zugang zu allen (statischen) Eigenschaften der äußeren Klasse Gilt auch umgekehrt Innere Klasse existiert unabhängig von Instanzen der äußeren Klasse Compiler generiert innere Klasse als normale Klasse mit einigen Spezialfunktionen Name ist ÄußereKlasse$InnereKlasse © Prof. Dr. Björn Dreher Programmieren 2 - Java 149 3 4 Innere Klassen 4.2 Geschachtelte statische Klasse Beispiel: Verkettete Liste LinkedStack I/F Linkable head LinkableInteger int i int i int i next next next = null public class LinkedStack { // This static member interface defines how objects are linked public static interface Linkable { public Linkable getNext(); public void setNext(Linkable node); } // The head of the list is a Linkable object Linkable head = null; Statische innere Schnittstelle public void push(Linkable node) { intern genutzt node.setNext(head); head = node; } © Prof. Dr. Björn Dreher 150 Programmieren 2 - Java 4 Innere Klassen 4.2 Geschachtelte statische Klasse Beispiel: Verkettete Liste (fortgesetzt) LinkedStack I/F Linkable head LinkableInteger int i int i int i next next next = null ... public Linkable pop() { if (head !=null) { Linkable node = head; head = head.getNext(); return node; } return null; } } © Prof. Dr. Björn Dreher Programmieren 2 - Java 151 4 4 Innere Klassen 4.2 Geschachtelte statische Klasse Beispiel: Implementierung der statischen inneren Schnittstelle LinkedStack I/F Linkable head LinkableInteger int i int i int i next next next = null // This class implements the static member interface class LinkableInteger implements LinkedStack.Linkable { // Here's the node's data and constructor int i; public LinkableInteger(int i) { this.i = i; } Statische innere Schnittstelle extern genutzt // Here are the data and methods required to implement the interface LinkedStack.Linkable next; public LinkedStack.Linkable getNext() { return next; } public void setNext(LinkedStack.Linkable node) { next = node; } } © Prof. Dr. Björn Dreher 152 Programmieren 2 - Java 4 Innere Klassen 4.2 Geschachtelte statische Klasse Beispiel: Hauptprogramm LinkedStack I/F Linkable head LinkableInteger int i int i int i next next next = null public class TestInnerStaticClass { public static void main(String[] arg) { LinkedStack ls = new LinkedStack(); LinkableInteger li; for (int i = 1; i < 11; i++) ls.push(new LinkableInteger(i)); while ((li = (LinkableInteger) ls.pop()) != null) System.out.println(li.i); } } © Prof. Dr. Björn Dreher Programmieren 2 - Java 153 5 Programmieren 2 – Java Überblick: 4. Innere Klassen 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Einleitung Geschachtelte statische Klassen Elementklassen Lokale Klassen Anonyme innere Klassen Beispiele Pakete © Prof. Dr. Björn Dreher Programmieren 2 - Java 154 4 Innere Klassen 4.3 Elementklassen Engl.: Member class Vergleichbar mit normalem, nicht statischem Attribut Innere Klasse kann auf Attribute der äußeren Klasse zugreifen Auch auf die privaten! Innere Klassen dürfen selbst keine statischen Attribute oder Methoden definieren public class Rahmen { String s = "kringelich"; class Muster { void standard() { System.out.println( s ); } static void immer() { } // Fehler } } © Prof. Dr. Björn Dreher Programmieren 2 - Java 155 6 4 Innere Klassen 4.3 Elementklassen Weitere Eigenschaften Instanz der inneren Elementklasse kann nur existieren, wenn auch einen Instanz der äußeren Klasse existiert Sie gehört zu der äußeren Klasse Erzeugung einer Instanz der inneren Klasse Aus einer Methode der äußeren Klasse ganz normal mit dem new Operator Erzeugung von außen Man benötigt eine Referenz auf das äußere Objekt Rahmen r = new Rahmen(); // Äußere Klasse Muster m = r.new Muster(); Referenz der oder kürzer äußeren Klasse Muster m = new Rahmen().new Muster(); © Prof. Dr. Björn Dreher Programmieren 2 - Java 156 4 Innere Klassen 4.3 Elementklassen this Referenz this Referenz der umgebenden Klasse Rahmen Unser Beispiel: Rahmen.this Kann auch verwendet werden, um an verdeckte Eigenschaften der äußeren Klasse zu gelangen public class Rahmen { String s = "Rahmen-String"; class Muster { String s = "Muster-String" void standard() { System.out.println( Rahmen.this.s ); System.out.println( s ); } } } © Prof. Dr. Björn Dreher Programmieren 2 - Java 157 7 4 Innere Klassen 4.3 Elementklassen Mehrfach verschachtelte innere Klassen class Haus { String s = "Haus"; class Zimmer { String s = "Zimmer"; class Stuhl { String s = "Stuhl"; void ausgabe() { System.out.println( System.out.println( System.out.println( System.out.println( System.out.println( } } } s ); // Stuhl this.s ); // Stuhl Stuhl.this.s ); // Stuhl Zimmer.this.s ); // Zimmer Haus.this.s ); // Haus } public static void main( String args[] ) { new Haus().new Zimmer().new Stuhl().ausgabe(); } © Prof. Dr. Björn Dreher 158 Programmieren 2 - Java 4 Innere Klassen 4.3 Elementklassen Erzeugen verschachtelter Objekte Haus h = new Haus; Haus.Zimmer z = h.new Zimmer(); Haus.Zimmer.Stuhl s = z.new Stuhl(); s.ausgabe(); // // // // Instanz Instanz Instanz Methode von von von vom Haus Zimmer in h Stuhl in z Stuhl Verwechslungsgefahr bei Haus.Zimmer.Stuhl mit Paket-Hierarchie java.util.Date Groß-/Kleinschreibungskonventionen helfen hierbei! Man sollte sie einhalten! © Prof. Dr. Björn Dreher Programmieren 2 - Java 159 8 4 Innere Klassen 4.3 Elementklassen Beispiel: Verkettete Liste mit Enumeration Schnittstelle Enumeration for (Enumeration e = ls.enumerate(); e.hasMoreElements(); ) { System.out.println(e.nextElement()); } LinkedStack Enumerator Linkable current I/F Linkable head © Prof. Dr. Björn Dreher LinkableInteger int i int i int i next next next = null Programmieren 2 - Java 160 4 Innere Klassen 4.3 Elementklassen Klasse LinkedStack modifiziert public class LinkedStack { // This static member interface defines how objects are linked public static interface Linkable { ... } // The head of the list is a Linkable object Linkable head = null; // Methods (bodies omitted) public void push(Linkable node) { ... } public Linkable pop() { ... } // This Method returns an Enumeration object for this LinkedStack public java.util.Enumeration enumerate() { return new Enumerator(); } ... © Prof. Dr. Björn Dreher Programmieren 2 - Java 161 9 4 Innere Klassen 4.3 Elementklassen Klasse LinkedStack: Innere Klasse Enumerator ... // Implementation of Enumeration interface as member class protected class Enumerator implements java.util.Enumeration { Linkable current; // Constructor; uses private head field of containing class public Enumerator() { current = head; } public boolean hasMoreElements() { return (current != null; } public Object nextElement() { if (current == null) throw new java.util.NoSuchElementException(); Object value = current; current = current.getNext(); return value; } } } Enumerator Klasse als Hilfsklasse (helper class) der Klasse LinkedStack © Prof. Dr. Björn Dreher Programmieren 2 - Java 162 4 Innere Klassen 4.3 Elementklassen Klasse LinkedStack: Hauptprogramm import java.util.Enumeration; public class TestInnerClasses { public static void main(String[] arg) { LinkedStack ls = new LinkedStack(); LinkableInteger li; for (int i = 1; i < 11; i++) ls.push(new LinkableInteger(i)); Enumeration e = ls.enumerate(); while (e.hasMoreElements()) { Object o = e.nextElement(); if (o instanceof LinkableInteger) System.out.println( ((LinkableInteger)o).i); } System.out.println(); while ((li = (LinkableInteger) ls.pop()) != null) System.out.println(li.i); } } © Prof. Dr. Björn Dreher Programmieren 2 - Java 163 10 Programmieren 2 – Java Überblick: 4. Innere Klassen 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Einleitung Geschachtelte statische Klassen Elementklassen Lokale Klassen Anonyme innere Klassen Beispiele Pakete © Prof. Dr. Björn Dreher Programmieren 2 - Java 164 4 Innere Klassen 4.4 Lokale Klassen Sehr ähnlich wie innere Elementklassen Jedoch nicht als Eigenschaft der Klasse definiert, sondern lokal in einem Anweisungsblock einer Methode oder in einem Initialisierungsblock Kann auf Methoden der äußeren Klasse zugreifen Kann nur auf Attribute der äußeren Klasse zugreifen, die als final deklariert sind! Modifizierer public, protected, private und static sind nicht erlaubt © Prof. Dr. Björn Dreher Programmieren 2 - Java 165 11 4 Innere Klassen 4.4 Lokale Klassen Beispiel public class DrinnenMachtSpass { public static void main( String args[] ) { int i = 2; final int j = 3; class In { In() { System.out.println( j ); System.out.println( i ); // Fehler } } In in = new In(); } Zugriff nur auf final Attribute } © Prof. Dr. Björn Dreher Programmieren 2 - Java 166 4 Innere Klassen 4.4 Lokale Klassen Unser LinkedStack Beispiel // This Method returns an Enumeration object for this LinkedStack public java.util.Enumeration enumerate() { // Definition of Enumerator as local class class Enumerator implements java.util.Enumeration { Linkable current; // Constructor; uses private head field of containing class public Enumerator() { current = head; } public boolean hasMoreElements() { return (current != null; } public Object nextElement() { if (current == null) throw new java.util.NoSuchElementException(); Object value = current; current = current.getNext(); return value; } } // Return Instance of Enumerator class defined directly above return new Enumerator(); } } © Prof. Dr. Björn Dreher Programmieren 2 - Java 167 12 Programmieren 2 – Java Überblick: 4. Innere Klassen 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Einleitung Geschachtelte statische Klassen Elementklassen Lokale Klassen Anonyme innere Klassen Beispiele Pakete © Prof. Dr. Björn Dreher Programmieren 2 - Java 168 4 Innere Klassen 4.5 Anonyme innere Klassen Ähnlich wie lokale innere Elementklassen Jedoch ohne Namen Erzeugen immer genau ein Objekt Klassendefinition und Objekterzeugung in einem Ausdruck (kann Teil eines längeren Ausdrucks sein) new SuperKlasse() { // Innere Klasse } Anonyme Klasse ist Nachfahre von SuperKlasse oder new Schnittstelle() { // Innere Klasse } Anonyme Klasse implementiert Schnittstelle und ist Nachfahre von Object © Prof. Dr. Björn Dreher Programmieren 2 - Java 169 13 4 Innere Klassen 4.5 Anonyme innere Klassen Weitere Eigenschaften Keine zusätzliche extends oder implements Angaben möglich Sonst wie lokale Klassen Beispiel: Anonyme Klasse als Nachfahre von java.util.Date import java.util.*; public class InnerToStringDate { public static void main( String args[] ) { int i = 2; final int j = 3; Methode toString() wird überschrieben Date d; d = new Date() { public String toString() { return getDate() + "." + (getMonth()+1) + "." + (1900+getYear()); } }; System.out.println( d ); } } © Prof. Dr. Björn Dreher Programmieren 2 - Java 170 4 Innere Klassen 4.5 Anonyme innere Klassen Konstruktoren Ohne Namen ist auch kein Konstruktor möglich Ausweg: Instanzeninitialisierer als Initialisierungsblock import java.awt.*; public class AnonymUndInnen { public static void main( String args[] ) { System.out.println( new Point() { { x = -1; y = -1; } super() wird }.getLocation() ); automatisch aufgerufen! System.out.println( new Point(-1,0) { { y = -1; } }.getLocation() ); super(-1, 0) wird } automatisch aufgerufen! } Das geht natürlich auch einfacher: new Point(-1, -1).getLocation() © Prof. Dr. Björn Dreher Programmieren 2 - Java 171 14 4 Innere Klassen 4.5 Anonyme innere Klassen Konstruktoren (fortgesetzt) Da super() automatisch aufgerufen wird, ist expliziter Aufruf verboten Weiteres Beispiel new java.math.BigDecimal("12345678901234567890") { { System.out.println(toString()); } }; Ausgabe im Instanzeninitialisierer © Prof. Dr. Björn Dreher Programmieren 2 - Java 172 4 Innere Klassen 4.5 Anonyme innere Klassen Unser LinkedStack Beispiel // This Method returns an Enumeration object for this LinkedStack public java.util.Enumeration enumerate() { // Anonymous class is defined as part of return statement return new java.util.Enumeration { Linkable current; // Replace constructor with instance initializer { current = head; } public boolean hasMoreElements() { return (current != null; } public Object nextElement() { if (current == null) throw new java.util.NoSuchElementException(); Object value = current; current = current.getNext(); return value; } }; // Termination of return statement! } © Prof. Dr. Björn Dreher Programmieren 2 - Java 173 15 Programmieren 2 – Java Überblick: 4. Innere Klassen 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Einleitung Geschachtelte statische Klassen Elementklassen Lokale Klassen Anonyme innere Klassen Beispiele Pakete © Prof. Dr. Björn Dreher 174 Programmieren 2 - Java 4 Innere Klassen 4.6 Beispiele Implementierung einer verketteten Liste LinkedList Knoten - head: Knoten - tail: Knoten - data: Object - next: Knoten + add(o: Object): void + toString(): String + Knoten(o: Object) tail Knoten head © Prof. Dr. Björn Dreher data1 data2 data3 next next next = null Programmieren 2 - Java 175 16 4 Innere Klassen 4.6 Beispiele Implementierung einer verketteten Liste mit innerer Elementklasse public class LinkedList { private class Knoten { Object data; Knoten next; public String toString() { String s = ""; Knoten knoten = head; public Knoten( Object o ) { data = o; } while ( knoten != null ) { s = s + knoten.data + " "; knoten = knoten.next; } } private Knoten head, tail; public void add( Object o ) { Knoten n = new Knoten( o ); } return s; } } if ( tail == null ) head = tail = n; else { tail.next = n; tail = n; } © Prof. Dr. Björn Dreher 176 Programmieren 2 - Java 4 Innere Klassen 4.6 Beispiele Verkettete Liste: Hauptprogramm public class LinkedListDemo { public static void main( String args[] ) { LinkedList l = new LinkedList(); l.add( "Hallo" ); l.add( "Otto" ); System.out.println( l ); } } Ruft toString() der LinkedList auf © Prof. Dr. Björn Dreher Programmieren 2 - Java 177 17 4 Innere Klassen 4.6 Beispiele Funktionszeiger Interface FunktionsTest Function 0..* - MAX: int = 2 - func: Function[] = new Function[MAX] + calc(num: int): void + FunctionTest() + calc(i: int): void + main(args: String[]): void © Prof. Dr. Björn Dreher FunctionOne FunctionOne + calc(num: int): void + calc(num: int): void Programmieren 2 - Java 178 4 Innere Klassen 4.6 Beispiele Implementierung Funktionszeiger Zwei innere Klassen, die im Interface eingebettet sind public interface Function { public int calc( int num ); public class FunctionOne implements Function { public int calc( int num ) { return num*2; } } public class FunctionTwo implements Function { public int calc( int num ) { return num*4; } } } © Prof. Dr. Björn Dreher Programmieren 2 - Java 179 18 4 Innere Klassen 4.6 Beispiele Hauptprogramm: Funktionszeiger public class FunctionTest { final int MAX = 2; final Function[] func = new Function[MAX]; // Constructor public FunctionTest() { func[0] = new Function.FunctionOne(); func[1] = new Function.FunctionTwo(); } ... // Main program public static void main( String args[] ) { FunctionTest ft = new FunctionTest(); ft.calcAll( 42 ); } } public void calcAll(int n) { System.out.println("Funktion0" + func[0].calc(n) ); System.out.println("Funktion1" + func[1].calc(n) ); } ... © Prof. Dr. Björn Dreher Programmieren 2 - Java 180 Programmieren 2 – Java Überblick: 4. Innere Klassen 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Einleitung Geschachtelte statische Klassen Elementklassen Lokale Klassen Anonyme innere Klassen Beispiele Pakete © Prof. Dr. Björn Dreher Programmieren 2 - Java 181 19 4 Innere Klassen 4.7 Pakete Engl.: Package Thematisch zusammenhängende Klassen Normalerweise in einem zugehörigen Verzeichnis Verzeichnisname ist Paketname package süßigkeiten; class Zucker { ... } public class Schokolade extends Zucker { ... } © Prof. Dr. Björn Dreher Programmieren 2 - Java 182 4 Innere Klassen 4.7 Pakete Pakete nutzen import Anweisung package leckereien; import süßigkeiten.Schokolade; class Weihnachtsmann { Schokolade s; // sonst süßigkeiten.Schokolade } Wildcard Notation import java.awt.*; Achtung: In manchen Packages gibt es gleichnamige Klassen © Prof. Dr. Björn Dreher Programmieren 2 - Java 183 20 4 Innere Klassen 4.7 Pakete Übersetzen und Ausführen von Klassen in Paketen Aus dem den Paketen übergeordneten Verzeichnis javac –d %HOME%\java\classes packagename\dateiname.java Erzeugt Package-Verzeichnis unter classes Ausführen mit java packagename.dateiname © Prof. Dr. Björn Dreher Programmieren 2 - Java 184 21