Innere Klassen in Java Java 1.0: n ur top

Werbung
Innere Klassen in Java
Java 1.0: nur top-level Klassen
Seit Java Version 1.1: Innere Klassen
Deklaration einer Klasse innerhalb einer anderen Klasse
Illustration
Eigenschaften
Vorteile
(1)
Anwendungsmöglichkeiten
Varianten
Probleme
Literatur
Innere Klassen in Java
Illustration: Ein Auto hat Räder
class Auto{
// auessere Klasse
String marke;
// Instanz-Variable mit Identifier marke und Typ String
class Rad{
// innere Klasse
String material;
int radius;
}
Rad linkesRad = new Rad(); // Instanz-Variable mit Initialisierung
// alternativ this. new Rad()
}
(2)
Innere Klassen erlauben stärkere Strukturierung von Code!
}
public class AutoTest{
public static void main(String[] args){ // main Methode
Auto a1 = new Auto();
// Instanz a1 vom Typ Auto
a1.marke = "VW";
a1.linkesRad.material = "Holz";
a1.linkesRad.radius = 3;
System.out.println("Auto a1 hat ein Rad aus "+ a1.linkesRad.material);
}
Innere Klassen in Java
Eigenschaften Innerer Klassen
Zugriff: Der Code einer inneren Klasse kann auf alle Felder der
umschließenden Klasse zugreifen (mit den einfachen Namen)
class Auto{
String marke;
class Rad{
String material;
int radius;
void setMat(){if (marke == "VW") {material = "Gummi";}}
// Zugriff auf Feld marke der aeusseren Klasse
}
Rad linkesRad = new Rad();
void setMatLRad(){linkesRad.setMat();}
}
}
(3)
public class AutoTestExt{
public static void main(String[] args){
Auto a1 = new Auto();
a1.marke = "VW";
a1.setMatLRad();
System.out.println("Auto a1 hat ein Rad aus "+ a1.linkesRad.material);
}
Innere Klassen in Java
... Eigenschaften
// Zugriff auf Klasse Rad
Zugreifbarkeit: Der Name einer inneren Klasse ist nicht außerhalb ihres
Geltungsbereichs zugreifbar
class Auto{ ...
class Rad{ ... }
...
Rad linkesRad = new Rad();
}
}
public class AutoErr{
public static void main(String[] args){
Rad r1 = new Rad();
// Klasse Rad unbekannt
...
}
(4)
ERROR: Class Rad not found.
Innere Klassen in Java
... Eigenschaften
Compilation: AutoTest.class, Auto.class, Auto$Rad.class
Compilation innerer Klassen zu top-level Klassen unter Hinzufügung
einer Instanz-Variable für die aktuellen Werte der umschließenden Klasse
(5)
Damit sind innere Klassen (bisher) nur eine syntaktische Erweiterung der
Sprache Java, aber nicht der Plattform selbst!
class Auto$Rad{
private Auto this$0; // speichert Kopie von Auto.this
}
Innere Klassen in Java
Innere Klassen in Java
(6)
Vorteile von Inneren Klassen
Aufnahme des code as data Konzepts aus der funktionalen
Programmierung
Realisierung von “method pointers”: Senden von Stücken von Code von
einem Objekt zu einem anderen, wobei dieser Code Zugriff auf Felder des
sendenden Objekts hat
Bessere Strukturierung des Codes
ähnlich der Idee von nested functions (z. B. in der funktionalen
Programmierung); ABER: gilt hier nicht nur für Methoden, sondern für
ganze Objekte
Keine Sichtbarkeit nach Außen
name space eines package wird nicht “vollgemüllt”
... Vorteile von Inneren Klassen
Beispiel: Ereignisbezogene Programmierung, Benutzer-Schnittstellen
Programmierung mit Java’s AWT
}
class Counter{
int x;
class Listener implements ActionListener{
public void actionPerformed(ActionEvent e){x++;}
}
void listenTo(Button b){
b.addActionListener(new Listener());
}
Innere Klassen in Java
(7)
Das erzeugte Objekt Button inkremetiert den Zähler immer wenn es gedrückt wird
Methode listenTo erzeugt ein neues Listener Objekt und sendet es zu einem gegebenen Objekt der
Klasse Button
Methode der inneren Klasse Listener manipuliert Feld x der umschließenden Klasse Counter
Counter c = new Counter();
Button b = new Button(‘‘Press me’’);
c.listenTo(b);
gui.add(b);
Anwendungsmöglichkeiten
Für die ereignisbezogene Programmierung (Beispiel Listener)
Erzeugung von Adapter-Klassen: z. B. StackEnumeration,
ListEnumeration als Adapter innerhalb einer Klasse Stack/List
Definition abstrakter Datentypen (Liste, Stack): Listen-/Stack-Elemente
als innere Klassen (siehe Vorlesung “Informatik I”, Skript Kapitel 9)
Wissensrepräsentation: Schemahierarchien, verschachtelte strukturierte
Objekte (Beispiel Auto)
(8)
Realisierung von Closures: Funktionen, die ihren lexikalischen Kontext
erinnern und ihre freien Variablen darüber binden (funktionale
Programmierung)
Innere Klassen in Java
... Anwendungsmöglichkeiten
Beispiel: Closures in Common Lisp
[1]> (defun adder (n) (function (lambda (m) (+ m n))))
ADDER
[2]> (setq add3 (adder 3))
#<CLOSURE :LAMBDA (M) (+ M N)>
[3]> (funcall add3 4)
7
Für die innere, namenlose Funktion ist n eine freie Variable
(9)
Ergebnis von (adder 3) ist eine Funktion, die die Zahl 3 zu ihrem
Argument (m) addiert
Innere Klassen in Java
Varianten Innerer Klassen
Bisher: “echte” innere Klassen als member der umschließenden Klasse
weitere Möglichkeiten
– nested top-level Klassen (static innere Klasse)
– lokale Klassen (innerhalb einer Methode)
(10)
– anonyme Klassen (namenlose lokale Klassen)
Innere Klassen in Java
... Varianten Innerer Klassen
Nested Top-Level Klassen
}
public class AdderN{
static class Add3{
int add(int m){ return m+3; }
}
public static void main(String[] args){
Add3 add3 = new Add3();
System.out.println(add3.add(4));
}
Behandelt wie top-level Klassen (keine echten inneren Klassen)
Vorteil: package-ähnliche Organisation für Klassen in einer Datei
(11)
Zugriff auf alle (privaten) Felder
Innere Klassen in Java
Lokale Klassen
}
... Varianten Innerer Klassen
public class AdderL{
public static void main(String[] args){
class Add3{
int add(int m){ return m+3; }
}
Add3 add3 = new Add3();
System.out.println(add3.add(4));
}
Klasse innerhalb eines Blocks (einer Methode)
Zugriff auf Namen wie jeder andere Ausdruck im Block
Greift eine lokale Klasse auf (Instanz-) Variablen der umschließenden Klasse zu, so müssen diese in der
lokalen Klasse final sein!
(12)
Auch nachdem die Methode verlassen wurde, bleiben solche Variablen für das innere Objekt verfügbar
Innere Klassen in Java
Anonyme Klassen
interface Adder{
int add(int m);
}
}
... Varianten Innerer Klassen
public class AdderA{
public static void main(String[] args){
Adder add3 = new Adder(){
public int add(int m){ return m+3; }
};
System.out.println(add3.add(4));
}
Spezialfall einer lokalen Klasse; für kleine selbsterklärende Stücke Code
Kurzschreibweise für lokale Objekte
Eine new Anweisung kann mit einem Klassen-Körper enden
(13)
Da namenlos: keine Konstruktoren!
Innere Klassen in Java
}
Probleme mit Inneren Klassen
Compiliert mit JDK 1.1.7: I’m a C.D object,
compiliert mit JDK 1.2.2: I’m a C object
Unklare Beziehung zwischen inneren Klassen und Vererbung
(14)
Möglicherweise sollten die derzeit existierenden Freiheitsgrade
eingeschränkt werden (saubere Semantik!)
Innere Klassen in Java
Qualified this: Für eine innere Klasse C1.C2...Ci...Cn denotiert Ci.this die (n-i)-te
direkt umschließende Instanz; aber was ist, wenn Ci Superklasse von Cn ist?
class C {
void who(){ System.out.println("I’m a C object"); }
class D extends C{
void m(){ C.this.who(); }
void who(){ System.out.println("I’m a C.D object"); }
}
public static void main(String[] args){
new C().new D().m();
}
Java TM Tutorial:
Literatur
http://java.sun.com/docs/books/tutorial/post1.0/whatsnew/inner.html
http://java.sun.com/docs/books/tutorial/java/javaOO/innerclasses.html
Spezifikation Innerer Klassen von Sun:
http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/index.html
Chuck McManis (1997). Java In Depth: A look at inner classes, JavaWorld,
2(1).
http://www.javaworld.com/javaworld/jw-10- 1997/jw- 10-indepth.html
Brent W. Benson (1999). Java Reflections: Inner Classes: Closures for the
Masses. ACM SIG-PLAN Notices, 34(2), 32-35.
(15)
Atsushi Igarashi and Benjamin C. Pierce (to appear). On inner classes.
Information and Control.
http://www.graco.c.u-tokyo.ac.jp/˜igarashi/papers/ecoop00.html
Innere Klassen in Java
Herunterladen