Methoden |
sind nicht als Parameter erlaubt.
forall Routinen mit Funktionen als
Parameter zur Verarbeitung aller Elemente sind damit nicht möglich.
|
| |
Ausweg |
eine abstrakte Klasse mit einer Methode als
Kommando definieren
|
|
diese Klasse beerben und mit eigenen Methoden
konkretisieren
|
| |
dynamisches Binden |
durch Vererbung und dynamisches Binden
werden Methoden als Parameter simuliert
|
| |
Beispiel |
|
Command |
eine abstrakte Kommando-Klasse
|
|
abstract
public
class Command {
abstract
public
void process(Object o);
}
|
| |
PrintCommand |
eine konkrete Klasse für eine Ausgabe
|
|
public
class PrintCommand
extends Command
{
public
void process(Object o) {
System.out.println(o.toString());
}
}
|
| |
Anwendung |
eine einfache Array-Klasse mit einer
Methode zur Verarbeitung aller Elemente
|
Array |
public
class Array {
Object [] a;
public
void forall(Command c) {
for (int i = 0;
i < a.length;
++i ) {
c.process(a[i]);
}
}
public
void print() {
forall(new PrintCommand());
}
}
|
| |
|
die print-Methode verwendet
die forall-Kontrollstruktur wieder.
|
| |
|
die print-Methode ist
unabhängig von der konkreten Ausprägung der
forall-Kontrollstruktur
|
| |
|
die print-Methode kann
in eine abstrakte Oberklasse von Array
ausgelagert werden und von vielen Klassen genutzt werden.
|
| |
Beispiel |
|
Container |
eine abstrakte Oberklasse mit implementierter
print-Methode
|
|
abstract
public
class Container {
abstract
public
void forall(Command c);
public
void print() {
forall(new PrintCommand());
}
}
|
| |
Array1 |
eine abgeleitete Klasse, die nur die
forall-Kontrollstruktur
definiert
|
|
public
class Array1
extends Container
{
Object [] a;
public
void forall(Command c) {
for (int i = 0;
i < a.length;
++i ) {
c.process(a[i]);
}
}
}
|
| |
|
viele Methoden können so in
gemeinsamen Oberklassen nur einmal
implementiert und für
die unterschiedlichsten Datenstrukturen
wiederverwendet werden
|
| |
|
für jedes Kommando, auch für Kommandos, die nur
einmal verwendet werden, muss eine neue Kommando-Klasse
erstellt werden
|
| |
|
Namensraum der Klassen wird unnötig überfüllt.
|
|
|
| |
|
Kommandos können einen lokalen Zustand besitzen,
dieser wird durch einen Konstruktor mit Parametern
initialisiert
|
| |
Beispiel |
import java.io.PrintStream;
public
class PrintStreamCommand
extends Command
{
PrintStream ps;
public
PrintStreamCommand() {
this.ps = System.out;
}
public
PrintStreamCommand(PrintStream ps) {
this.ps = ps;
}
public
void process(Object o) {
ps.println(o.toString());
}
}
|
| |
Anwendung |
import java.io.PrintStream;
abstract
public
class Container1
extends Container
{
public
void print(PrintStream ps) {
forall(new PrintStreamCommand(ps));
}
}
|
| |
2. Beispiel |
Akkumulieren eines Resultats
|
|
Beispiel:
Berechnung der Summe aller Elemente
|
|
public
class SumCommand
extends Command
{
int sum;
public
SumCommand() {
sum = 0;
}
public
void process(Object o) {
sum += ((Integer)o).intValue();
}
public
int getSum() {
return
sum;
}
}
|
| |
Anwendung |
abstract
public
class Container2
extends Container1
{
public
int sum() {
SumCommand c = new SumCommand();
forall(c);
return
c.getSum();
}
}
|
| |
|
die Technik, Methoden in Objekten zu speichern,
und diese möglicherweise auch erst später aufzurufen,
wird intensiv für die Ereignisbehandlung eingesetzt.
|
| |
Beispiel |
|
| |
Beispiel |
|
| |