4. Innere Klassen

Werbung
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
Herunterladen