Info B VL 11: Innere Klassen/Collections

Werbung
Info B VL 11: Innere
Klassen/Collections
Objektorientiere Programmierung in Java
2003
Ute Schmid (Vorlesung)
Elmar Ludwig (Übung)
FB Mathematik/Informatik, Universität Osnabrück
Info B VL 11: Innere Klassen/Collections – p.254
Wiederholung: Innere Klassen
Vier Arten von inneren Klassen:
Member Classes (“echte” innere Klasse)
Static Member Classes (Nested Top-Level Classes)
Local Classes
Anonymous Classes
Info B VL 11: Innere Klassen/Collections – p.255
Lokale Klassen / Nachtrag
public class Test {
public static interface Value {
public int getValue ();
public void setValue (int i);
}
public Value[] foo () {
int value = 0;
class Local implements Value {
public int getValue () { return value; }
public void setValue (int i) { value = i; }
};
return new Value[] { new Local(), new Local() };
}
public static void main (String args[]) {
Test test = new Test();
Value[] v = test.foo(); // two value objects
v[0].setValue(42); v[1].setValue(24);
System.out.println(v[0].getValue()); // ???
}
}
Info B VL 11: Innere Klassen/Collections – p.256
Anonyme Klassen
Namenlose lokale Klassen
Kombination der Syntax von Klassen-Definition und
Objekt-Erzeugung
wie lokale Klassen innerhalb eines Ausdrucks definiert
Info B VL 11: Innere Klassen/Collections – p.257
‘Enumerator’ als anonyme Klasse
public java.util.Enumeration enumerate() {
// The anonymous class is defined as part of the
// return statement
return new java.util.Enumeration() {
protected int current = 0;
public boolean hasMoreElements() {
return current < numOfEls;
}
public Object nextElement() {
if (! hasMoreElements())
throw new java.util.NoSuchElementException();
return list[current++];
}
}; // semicolon required to finish return statement
}
Info B VL 11: Innere Klassen/Collections – p.258
Eigenschaften von Anonymen Kl. (1)
Lokale Klasse ohne Namen.
Definition und Instantiierung in einem einzigen
Ausdruck (new Operator).
( [
argument-list
] )
class-body
class-name
new
Zwei Formen:
interface-name
( )
class-body
new
Konstruktoraufruf der Oberklasse (evtl. auch
Default-Konstruktor), Erzeugung eines Objekts der
anonymen Unterklasse.
Default-Konstruktoraufruf für ein Interface, Erzeugung
einer anonymen Unterklasse von Object, die das
Interface implementiert.
Lokale Klasse ist Anweisung in einem Block, anonyme
Klasse Ausdruck als Teil eines grösseren Ausdrucks
(z.B. Methodenaufruf).
Info B VL 11: Innere Klassen/Collections – p.259
Eigenschaften von Anonymen Kl. (2)
Verwendung: lokale Klasse, die nur einmal benutzt
wird. (Definition und Nutzung genau dort, wo
verwendet; weniger “clutter” im Code)
Beschränkungen wie für lokale Klassen: keine
statischen Komponenten, ausser static final
Konstanten; nicht als public, private,
protected, static deklarierbar.
Da namenlos: keine Konstruktor-Definition möglich.
Erbt – ausnahmsweise – die Konstruktoren der
Oberklasse. Im Fall eines Interfaces wird ein
Default-Konstruktor eingefügt.
Wenn eigener/anderer Konstruktor notwendig, als
lokale Klasse definieren.
Alternative: Instanz-Initialisierer (für anonyme Klassen
eingeführt), Initialisierungsblock wird in die geerbten
Konstruktoren/den Default-Konstruktor eingefügt.
Info B VL 11: Innere Klassen/Collections – p.260
Implementation f. Lokale Klassen
Zusätzlich zu den Zugriffsrechten von
Member-Klassen, Zugriff auf final deklarierte lokale
Variablen im Geltungsbereich des Blocks, in dem sie
definiert sind.
Compiler gibt der inneren Klasse private
Instanzfelder, um Kopien der lokalen Variablen zu
halten.
Compiler fügt versteckte Parameter für jeden
Konstruktor einer lokalen Klasse ein, um diese
private Felder zu initalisieren.
Lokale Klasse hat nicht wirklich Zugriff auf die lokalen
Variablen, sondern auf eine private Kopie dieser
Variablen. final garantiert Konsistenz!
“Hoch”-Compilation von anonymen Klassen: Vergabe
von Nummern, z.B. MyListAC$1.class.
Info B VL 11: Innere Klassen/Collections – p.261
Adapter
Design Pattern sowie spezielle Java Adapter-Klassen.
Adapter: Konvertierung eines API einer Klasse in das
API einer anderen.
Anwendung: Zusammenarbeit unverbundener Klassen
Konzept: Schreibe Klasse mit dem gewünschten
Interface und lasse diese Klasse mit der Klasse
kommunizieren, die ein anderes Interface hat.
Zwei Möglichkeiten zur Realisierung:
Klassen-Adapter: Ableitung einer neuen Klasse
von der nicht-angepassten Klasse und Hinzufügen
von Methoden so, dass die neue Klasse dem
gewünschten Interface genügt.
Objekt-Adapter: Einbetten eines Objekts der
ursprünglichen Klasse in die neue Klasse und
Definition von Methoden, um Aufrufe in der neuen
Klasse entsprechend zu übersetzen.Info B VL 11: Innere Klassen/Collections – p.262
Klassen-Adapter
class A {
// a class which "nearly" meets specification B
}
interface B {
// ...
}
class AdA extends A implements B {
// implement methods of B using A
}
Info B VL 11: Innere Klassen/Collections – p.263
Objekt-Adapter
class AdA implements B {
A a;
// ...
}
Info B VL 11: Innere Klassen/Collections – p.264
Adapter für GUI-Prog.
In Java wird der Begriff “Adapter” für Klassen im
GUI-Bereich verwendet.
Hier sind Adapter-Klassen Klassen, die nur Methoden
mit leerem Körper zur Verfügung stellen.
Anwendung: Erzeugung eines entsprechenden
Objekts und Überschreiben der benötigten Methoden.
Info B VL 11: Innere Klassen/Collections – p.265
‘WindowAdapter’ (1)
class MyWindowAdapter extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
} }
public class Closer {
public Closer() {
MyWindowAdapter win = new MyWindowAdapter();
Frame f = new Frame();
f.addWindowListener(win);
f.setSize(new Dimension(100,100));
f.setVisible(true);
}
public static void main(String[] args) {
new Closer();
}
}
Info B VL 11: Innere Klassen/Collections – p.266
‘WindowAdapter’ (2)
Kompaktere Realisierung mit anonymer Klasse:
// create window listener for window close
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{System.exit(0);}
});
Info B VL 11: Innere Klassen/Collections – p.267
Innere Klassen und Lexical Closures
Lexical Closure: Funktion, die ihren Kontext erinnert
und freie Variablen darüber bindet.
Konzept aus der funktionalen Programmierung.
[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
Info B VL 11: Innere Klassen/Collections – p.268
Adder-Beispiel
interface Adder{
int add(int m);
}
public Adder makeAdder(final int n) {
return new Adder() {
public int add (int m) {return m + n;}
};
}
In makeAdder wird das Adder-Interface für eine
spezielle Anforderung adaptiert!
Die anonyme innere Klasse realisiert das Konzept der
lexical closure.
Info B VL 11: Innere Klassen/Collections – p.269
ADTs und Collections
Lernziele:
Wiederholung/Ergänzung zu ADTs
Illustration von OO-Prinzipien
Lernen des Lesens von fremdem Code
siehe Beispielprogramme im Paket adt
Info B VL 11: Innere Klassen/Collections – p.270
Herunterladen