Iterator - Universität Paderborn

Werbung
Wiederholung
Universität Paderborn
Prof. Dr. Heike Wehrheim
Interface (Schnittstelle) in Java:
benannte Menge von Methodenspezifikationen
ohne deren Implementierung
Definition durch
interface Sprechend {
// Methodenköpfe
}
Ein Interface definiert eine Rolle von Objekten / Sicht
auf Objekte
Ein Interface legt einen Vertrag fest.
GP1 WS 08/09
678
Andere Klassen können …
Universität Paderborn
Prof. Dr. Heike Wehrheim
ƒ das Interface implementieren
legen fest, wie sie die Methoden implementieren
wie ihre Objekte diese Rolle einnehmen
verpflichten sich dadurch zur Einhaltung des
Vertrags
class Bla implements Sprechend {
// Methodenimplementierungen
}
ƒ das Interface benutzen
können von der Einhaltung des Vertrags durch
implementierende Klassen ausgehen
benutzen Methoden des Interface ohne deren
Implementierung zu kennen
GP1 WS 08/09
679
Interface Namen …
Universität Paderborn
Prof. Dr. Heike Wehrheim
ƒ können als Typen für Variablen auftreten
Sprechend hugo;
ƒ ihnen können Objekte der
implementierenden Klassen zugewiesen
werden
hugo = new Bla();
GP1 WS 08/09
680
Mehrfachimplementierung
Universität Paderborn
Prof. Dr. Heike Wehrheim
Interfaces: gleicher Methodenname, unterschiedliche
Signatur
interface Tierisch {
interface Laufend{
void laufe();
void laufe (int km);
}
}
Implementierende Klasse:
public class Hund implements Laufend, Tierisch
{
public void laufe() {
System.out.println("Ich laufe langsam.");
}
public void laufe(int km) {
System.out.println("Ich laufe " + km +
" Stundenkilometer schnell.");
}}
GP1 WS 08/09
681
Benutzende Klasse
Universität Paderborn
Prof. Dr. Heike Wehrheim
class Hundebesitzer {
public static void main (String [] args) {
Hund bello = new Hund();
bello.laufe();
bello.laufe(10);
}
}
Hundebesitzer.java
GP1 WS 08/09
682
Universität Paderborn
Prof. Dr. Heike Wehrheim
Was passiert bei …
interface Tierisch {
void laufe();
}
interface Laufend {
void laufe (int km);
}
Laufend bello = new Hund();
bello.laufe(); // ?????
Laufend bello = new Laufend();
bello.laufe(5); // ?????
Laufend bello = new Hund();
((Hund) bello).laufe(); // ?????
Laufend bello = new Hund();
((Tierisch) bello).laufe(); // ?????
GP1 WS 08/09
683
Weitere Beispiele
Universität Paderborn
Prof. Dr. Heike Wehrheim
1. Zugriff auf Objekte mit Schlüsselwerten
TelefonListe.java
ƒ Die Schnittstelle beschreibt die Eigenschaft, daß
ein Objekt aus seinen internen Daten einen
Schlüsselwert vom Typ String bestimmt; dies
implementiert die Funktion String getKey().
interface HasKey {
String getKey();
// gib den Schlüsselwert für einen
// Datensatz zurück
}
danach kann man z.B. sortieren oder suchen
GP1 WS 08/09
684
Implementierende Klasse
Universität Paderborn
Prof. Dr. Heike Wehrheim
Die Klasse Telefon beschreibt Objekte, die das Geforderte
können:
class Telefon implements HasKey {
String name;
int telefonnr;
Telefon( String n , int tel ) {
name=n ; telefonnr=tel ;
}
public String getKey() {
return name ;
}
public String toString() {
return "( "+name+" : "+telefonnr+" )"; }
}
GP1 WS 08/09
685
Benutzung
Universität Paderborn
Prof. Dr. Heike Wehrheim
Telefon wird benutzt, um ein Telefonbuch als Array von
Telefon-Objekten anzulegen:
public static void main( String[] args ) {
Telefon [] telefonbuch = {
new Telefon( "Peter" , 12345 ) ,
new Telefon( "Anna" , 23753 ) ,
new Telefon( "Anton" , 12314 ) ,
new Telefon( "Monika", 44117 )
} ;
Jedes Telefon-Objekt ist ein spezielles HasKey-Objekt ⇒
ein Telefon []-Objekt ist ein spezielles HasKey []-Objekt ⇒
wir können eine Methode, die ein HasKey []-Objekt sortiert,
benutzen, um telefonbuch zu sortieren
sort(telefonbuch) ;
// sortiert Telefonbuch nach Namen
static void sort( HasKey[] arr ) { ... }
GP1 WS 08/09
686
Implementierung von sort
Universität Paderborn
Prof. Dr. Heike Wehrheim
Verwendet nur die „getKey-Eigenschaft“ von HasKey-Objekten
static void sort( HasKey[] arr ) {
int left , min , test ;
for ( left=0; left < arr.length-1; left++) {
min = left;
for(test = left+1;test < arr.length;test++){
if (arr[test].getKey().compareTo(
arr[min].getKey() ) < 0)
min = test;
}
tausche(arr,min,left);
}}
static void tausche( HasKey[] arr, int l, int m) {
HasKey hilf
= arr[l];
arr[l] = arr[m];
arr[m] = hilf;
}
GP1 WS 08/09
687
2. Beispiel
Universität Paderborn
Prof. Dr. Heike Wehrheim
Interface für Sortierfunktionen
ƒ Ziel:
Sortierfunktionen unabhängig von dem Elementtyp
formulieren
ƒ Voraussetzung:
Es gibt eine Ordnungsfunktion lessThan für den
Elementtyp.
Sortieralgorithmus nutzt ausschließlich diese Eigenschaft
der zu sortierenden Objekte.
interface Sortable {
boolean lessThan (Sortable a);
}
die zu sortierenden Objekte müssen von Klassen stammen,
die Sortable implementieren
GP1 WS 08/09
688
Sortiermethode
Universität Paderborn
Prof. Dr. Heike Wehrheim
Nimmt nur an, das Parameter ein Array von
„sortierbaren“ Objekten ist
static void selectSort (Sortable [] arr) {
for (int left = 0;left < arr.length-1;
left++) {
int min = left;
for (int j = left+1; j < arr.length;
j++)
if (arr[j].lessThan (arr[min]))
min = j;
// left und min tauschen
Sortable tmp
= arr[min];
arr[min] = arr[left];
arr[left] = tmp;
}
}
GP1 WS 08/09
689
Verwendung
Für die Klasse Telefon:
Universität Paderborn
Prof. Dr. Heike Wehrheim
Telefonliste2.java
class Telefon implements Sortable {
int telefonnr;
String name;
...
// Konstruktor, Methoden
public boolean lessThan (Sortable a) {
return name.compareTo(((Telefon)a ).name )<0;
}
}
...
Telefon [] telefonbuch;
selectSort(telefonbuch);
...
ergibt Sortierung nach dem Namen
GP1 WS 08/09
690
Ändern der Sortierungsart
Universität Paderborn
Prof. Dr. Heike Wehrheim
Sortierung nach Telefonnummern durch Austausch der
„lessThan“-Methode:
public boolean lessThan(Sortable a) {
return telefonnr < ( (Telefon) a).telefonnr;
}
Änderung in der Klasse Telefon!
ƒ Klasse Telefonliste weiß davon nichts und muß auch davon
nichts wissen
ƒ Telefonliste geht davon aus, daß der im Interface Sortable
festgelegte „Vertrag“ (= es gibt eine Methode lessThan mit der
angegeben Signatur) eingehalten wird
und das bleibt auch bei Änderung der Implementierung bestehen
GP1 WS 08/09
691
Was darf man, was nicht?
Universität Paderborn
Prof. Dr. Heike Wehrheim
ƒ Schnittstellen spezifizieren Methoden mit
Signaturen, geben aber nie Implementierungen an
ƒ die Methoden der Interfaces sind immer public,
auch wenn man es nicht hinschreibt
ƒ Interfaces spezifizieren keine Konstruktoren
ƒ es werden nie Objekte von Interfaces erzeugt;
new Tierisch(); geht nicht!
ƒ Interfaces definieren keine Variablen (Ausnahme:
static final Variablen)
ƒ Interfaces definieren keine static Methoden
GP1 WS 08/09
692
Ein Interface aus java.util
Universität Paderborn
Prof. Dr. Heike Wehrheim
Iterator<E>
ƒ Schnittstelle spezifiziert Methoden zur Aufzählung der
Elemente einer Datenstruktur (zur Iterierung über die
Elemente)
ƒ Der Typ der Elemente ist über E wählbar (generisches
Interface), d.h. das Interface ist parametrisiert im Typ der
aufzuzählenden Elemente
ƒ Die implementierenden Klassen von Iterator geben an,
wie die Elemente aufgezählt werden können
ƒ Die aufzuzählende Struktur (Klasse für die Datenstruktur)
muss eine Methode haben, um ein „passendes“
Iterator-Objekt (das weiß, wie aufgezählt werden soll)
zu erzeugen.
(d.h., nicht die Datenstruktur/Klasse selber implementiert
das Interface, sondern sie kann Objekte einer Iteratorimplementierenden Klasse zurückliefern)
GP1 WS 08/09
693
Iterator
Universität Paderborn
Prof. Dr. Heike Wehrheim
Iterator<E> ist ein in java.util vordefiniertes Interface:
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
E ist ein Platzhalter für den Typ der Elemente, hier
können nachher beliebige Referenztypen
eingebaut werden
GP1 WS 08/09
694
Methoden von Iteratoren
Universität Paderborn
Prof. Dr. Heike Wehrheim
Ein Iterator-Objekt e erzeugt die Aufzählung mit
zwei Methoden:
e.hasNext()
liefert true, wenn e noch
nicht alle Elemente
durchlaufen hat
e.next()
liefert das nächste Element
(remove löscht das zuletzt von next gelieferte
Element)
GP1 WS 08/09
695
Universität Paderborn
Prof. Dr. Heike Wehrheim
Anschaulich
Bewegung eines Iterators
Element
Element
next
next
Element
Element
Element
next
next
next
Iterator
hasNext: true
GP1 WS 08/09
true
true
true
true
false
696
Beispiel: Scanner
Universität Paderborn
Prof. Dr. Heike Wehrheim
Scanner ist eine Iterator
implementierende Klasse,
und zwar für Iterator<String>:
ƒ boolean hasNext();
ƒ String next();
ƒ void remove();
GP1 WS 08/09
697
Anwendungsbeispiel
Universität Paderborn
Prof. Dr. Heike Wehrheim
Iterieren durch die Eingabe
Scanner sc =
new Scanner(System.in);
while (sc.hasNext())
System.out.println(sc.next());
Gib alles aus, was über das Terminal
eingegeben wird (Ende bspw. mit Ctrl-C.)
GP1 WS 08/09
698
Beispiel: ArrayList
Universität Paderborn
Prof. Dr. Heike Wehrheim
Datenstruktur ArrayList
Speicherung von Werten in einer bestimmten
Ordnung
(ähnlich Arrays, aber flexibel in der Länge)
ArrayList ist eine Klasse, die ein Objekt vom Typ
Iterator liefern kann,
dieses kann zur Aufzählung benutzt werden
(ArrayList und Iterator sind Teil des
sogenannten Collection-Frameworks; falls Zeit,
später mehr)
GP1 WS 08/09
699
ArrayList
Universität Paderborn
Prof. Dr. Heike Wehrheim
ƒ Array-ähnliche Datenstruktur, die aber selber „mitwächst“
ƒ Anfangskapazität wird angegeben; wird diese überschritten,
wird automatisch ein neues, größeres Array erzeugt
ƒ Wie HashMap generische Klasse, der Typ der Elemente
muss angegeben werden: ArrayList<E>
(Ein) Konstruktor:
ArrayList(int initialCapacity)
(Einige) Methoden:
E get(int index)
E remove(int index)
boolean add(E element)
E set(int index, E element)
int size()
Funktionalität siehe API
GP1 WS 08/09
700
Benutzung
Universität Paderborn
Prof. Dr. Heike Wehrheim
// Anfangskapazität 10
ArrayList<Integer> arr =
new ArrayList<Integer>(10);
// 20 Elemente einfügen
for(int i = 0; i < 20; i++)
arr.add(i,i);
20 Elemente einfügen funktioniert, obwohl anfangs nur für 10
deklariert!
Aus Effizienzgründen (Zeit, Platz) versuchen, die
Anfangskapazität passend zu wählen.
GP1 WS 08/09
701
ArrayList und Iterator
Universität Paderborn
Prof. Dr. Heike Wehrheim
ArrayList<E> hat Methode
Iterator<E> iterator()
Damit kann man an ein Iterator-Objekt zu einem
ArrayList-Objekt kommen; dieses kann zur
Aufzählung benutzt werden
Iterator<Integer> e = arr.iterator();
while (e.hasNext())
System.out.println(e.next());
ALTest.java
GP1 WS 08/09
702
Eigene Iteratoren
Universität Paderborn
Prof. Dr. Heike Wehrheim
Man kann auch selber eine Klasse schreiben, die
das Interface Iterator implementiert.
Wofür kann das gut sein?
ƒ Haben eigene Datenstruktur zum Speichern von
Elementen geschrieben, nun möchten wir einen
Iterator dafür haben.
ƒ Wollen einen speziellen Iterator haben, der eine
bestimmte Art der Aufzählung macht.
(Folgendes Beispiel aus Arnold, Gosling, Holmes: The Java
Programming Language)
GP1 WS 08/09
703
Anwendungsbeispiel
Universität Paderborn
Prof. Dr. Heike Wehrheim
Beispiel: ShortStringIterator
Ziel: Ein Iterator für Folgen von Zeichenketten schreiben, der
nur Zeichenketten bis zu einer bestimmten Länge ausgibt
(also ein Iterator, der gleichzeitig filtert).
Dieser Iterator benutzt einen anderen Iterator (im folgenden
Ursprungsiterator genannt), der alle Elemente aufzählt. Aus
dieser Aufzählung werden dann die entsprechenden
Zeichenketten herausgefiltert.
Basisidee: um an das nächste Element zu kommen, wird
solange ein Element aus der Ursprungsiteration erzeugt,
bis diese entweder leer ist oder eine „kurze“ Zeichenkette
gefunden wurde.
GP1 WS 08/09
704
ShortStringIterator
Universität Paderborn
Prof. Dr. Heike Wehrheim
Objektvariablen:
Iterator<String> it
der zu benutzende Ursprungsiterator
String nextShort
Variable zur Speicherung des nächsten Strings; null, falls
keiner gefunden wurde
int maxLen
Maximal zulässige Länge der herauszufilternden
Zeichenketten
Objektmethoden: (diese fordert Interface Iterator)
(Konstruktor)
hasNext()
next()
remove()
GP1 WS 08/09
705
Universität Paderborn
Prof. Dr. Heike Wehrheim
In Java
public class ShortStringIterator implements
Iterator<String> {
private Iterator<String> it;
private String nextShort;
private final int maxLen;
Ursprungsiterator
public ShortStringIterator( Iterator<String>
it, int maxLen) {
this.it = it;
this.maxLen = maxLen;
nextShort = null;
}
nextShort am Anfang null:
noch nichts gefunden
GP1 WS 08/09
706
…
Universität Paderborn
Prof. Dr. Heike Wehrheim
public boolean hasNext() {
Nach nächstem kurzen
if (nextShort != null) return true;
String suchen
while (it.hasNext()) {
nextShort = it.next();
if (nextShort.length() <= maxLen)
return true;
}
Gefunden? Dann
nextShort = null;
fertig!
return false;
}
Achtung: Nebeneffekt!
public String next() {
if (nextShort == null && ! hasNext())
throw new NoSuchElementException();
String n = nextShort;
Exception werfen, wenn next
nextShort = null;
aufgerufen wird, obwohl kein
return n;
nächstes Element existiert
}
GP1 WS 08/09
707
…
Universität Paderborn
Prof. Dr. Heike Wehrheim
public void remove() {
throw new
UnsupportedOperationException();
}
Konvention des Collection Frameworks: nicht
unterstützte Methoden werfen
UnsupportedOperationException
ShortStringIterator.java
GP1 WS 08/09
708
Benutzung davon
Universität Paderborn
Prof. Dr. Heike Wehrheim
Zwei Beispiele: a) der Ursprungsiterator ist ein Scanner und b) der
Ursprungsiterator ist der Iterator einer ArrayList
Scanner sc = new Scanner("Dies ist eine Zeichenkette
mit langen und mit kuerzeren Worten …“);
ShortStringIterator it =
new ShortStringIterator(sc,6);
while (it.hasNext())
System.out.print( it.next() + " ");
ArrayList<String> arr = new ArrayList<String>(10);
// arr füllen
ShortStringIterator it2 =
new ShortStringIterator(arr.iterator(),6);
while (it2.hasNext() )
System.out.print( it2.next() + " ");
ShortStringApplication.java
GP1 WS 08/09
709
Zusammenfassung
Universität Paderborn
Prof. Dr. Heike Wehrheim
Interface (Schnittstelle) in Java:
ƒ Eine benannte Menge von
Methodenspezifikationen - ohne deren
Implementierung:
interface Movable {
boolean start ();
void stop ();
boolean turn (int degrees);
}
ƒ Interfaces spezifizieren bestimmte Sichten/Rollen
ƒ Interfaces legen Verträge fest
(Methodensignaturen), die die implementierenden
Klassen einhalten müssen
GP1 WS 08/09
710
In Klassen
Universität Paderborn
Prof. Dr. Heike Wehrheim
ƒ Klassen können bestimmte, hinter implements aufgeführte
Interfaces implementieren (auch mehrere):
class Bike implements Movable {
public boolean start () {...}
// Implementierung von stop und turn sowie
// weiterer Methoden
...
}
class Car implements Movable, Motorized {
// Implementierung der Methoden aus Movable
// und Motorized, sowie weiterer
...
}
ƒ damit können ihre Objekte die in den Interfaces festgelegten
Rollen einnehmen
ƒ mit der Implementierung „sagt“ die Klasse, daß sie den Vertrag
der Schnittstelle einhält
GP1 WS 08/09
711
Interface als Typabstraktion
Universität Paderborn
Prof. Dr. Heike Wehrheim
ƒ Interfaces werden als Typabstraktion verwendet (Typ von
Variablen):
Movable vehicle;
...
vehicle = new Bike();
...
vehicle.turn(20);...
ƒ Typische Anwendung: Spezifikation von Eigenschaften
(Movable) oder Rollen, damit Algorithmen möglichst
allgemein formuliert werden können:
void drive (Movable vehicle, Coordinate
from, Coordinate to) {
vehicle.start ();
vehicle.turn (45);
vehicle.stop ();
...
}
GP1 WS 08/09
712
Herunterladen