23. Vorlesung (23.01.2014)

Werbung
Algorithmen und Datenstrukturen
Wintersemester 2013/14
23. Vorlesung
Interfaces und Generics
Krzysztof Fleszar
Lehrstuhl für Informatik I
1
Übersicht
InsertionSort
• für Punkte
Einschub: Liste für Objekte beliebiger Klassen
• für Objekte beliebiger Klassen
Einschub: Liste für Objekte von Klassen,
die ein(e) Nutzer(in) festlegen kann
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
2
Übersicht
InsertionSort
• für Punkte (Wiederholung vom 19.12.2013)
Einschub: Liste für Objekte beliebiger Klassen
• für Objekte beliebiger Klassen
Einschub: Liste für Objekte von Klassen,
die ein(e) Nutzer(in) festlegen kann
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
3
InsertionSort für Punkte
Ein Punkt in der Ebene:
UML-Diagramm:
public class Punkt {
public double x;
public double y;
}
Punkt
+x:double
+y:double
Voraussetzung fürs Sortieren:
Definition einer Ordnung
y
pi < pj genau dann, wenn
p3
pi.x < pj.x oder
p1
p2
1
0
( pi.x = pj.x und pi.y < pj.y)
p4
= lexikographische Ordnung
0
1
x
4
InsertionSort für Punkte
Ein Punkt in der Ebene:
UML-Diagramm:
public class Punkt {
Punkt
public double x;
+x:double
public double y;
+y:double
public Punkt(double myX, double myY) {
+Punkt(double, double)
x = myX;
+compareTo(Punkt):int
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
5
}
InsertionSort für Punkte
public class Sortierverfahren {
public static void insertionSort(int[] a) {
for (int j = 1; j < a.length; j++) {
int key = a[j];
int i = j - 1;
while (i >= 0 && a[i] > key) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
6
InsertionSort für Punkte
public class Sortierverfahren {
public static void insertionSort(Punkt[] a) {
for (int j = 1; j < a.length; j++) {
Punkt key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
7
InsertionSort für Punkte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static void insertionSort(Punkt[] a) {
//...
}
}
8
InsertionSort für Punkte
Problem:
eigene Sortiermethode für jede Klasse
public static void insertionSort(Punkt[] a) {
//...
}
9
Übersicht
InsertionSort
Einschub
• für Punkte (Wiederholung vom 19.12.2013)
Einschub: Liste für Objekte beliebiger Klassen
• für Objekte beliebiger Klassen
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
10
Liste für Punkte
x
head
nil
y
prev key next
nil
public class PunktListenElement {
public Punkt key;
public PunktListenElement prev;
public PunktListenElement next;
public PunktListenElement(Punkt k, PunktListenElement p) {
key = k;
next = p;
prev = null;
}
11
}
Liste für Punkte
public class PunktListe {
public PunktListenElement head;
public PunktListenElement insert(Punkt k) {
PunktListenElement x = new PunktListenElement(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class PunktListenElement {
public Punkt key;
public PunktListenElement prev;
public PunktListenElement next;
public PunktListenElement(Punkt k, PunktListenElement p) {
key = k;
next = p;
prev = null;
}
12
}
Liste für Punkte
public class PunktListenTest {
public static void main(String[] args) {
PunktListe l = new PunktListe();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (PunktListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Problem:
eigene Liste für jede Klasse notwendig
Lösung:
erstelle Liste für Objekte der Klasse java.lang.Object
13
Liste für Objekte
java.lang.Object
Punkt
• Jede Java-Klasse ist Unterklasse der Klasse java.lang.Object
• Eine Liste, die Objekte vom Typ java.lang.Object aufnehmen kann,
kann also jedes Objekt aufnehmen.
14
Liste für Objekte
public class PunktListe {
public PunktListenElement head;
public PunktListenElement insert(Punkt k) {
PunktListenElement x = new PunktListenElement(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class PunktListenElement {
public Punkt key;
public PunktListenElement prev;
public PunktListenElement next;
public PunktListenElement(Punkt k, PunktListenElement p) {
key = k;
next = p;
prev = null;
}
15
}
Liste für Objekte
public class Liste {
public ListenElement head;
public ListenElement insert(Object k) {
ListenElement x = new ListenElement(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class ListenElement {
public Object key;
public ListenElement prev;
public ListenElement next;
public ListenElement(Object k, ListenElement p) {
key = k;
next = p;
prev = null;
}
}
16
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
Compiler: "p.key.x cannot be resolved or is not a field"
}
17
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListenElement p = l.head; p != null; p = p.next) {
Punkt myPunkt = (Punkt) p.key; //explizite Typkonvertierung
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
Ausgabe:
1.0 0.0
2.0 2.0
0.0 1.0
18
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
Wir können nun auch Objekte
anderer Klassen in die Liste einfügen
}
}
19
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
Punkt myPunkt = (Punkt) p.key; //explizite Typkonvertierung
System.out.println(myPunkt.x + " " + myPunkt.y);
}
Ausgabe: Exception in thread "main"
}
}
java.lang.ClassCastException:
java.lang.Integer cannot be cast to Punkt
at ListenTest.main(ListenTest.java:12)
20
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
if (p.key instanceof Punkt) {
Punkt myPunkt = (Punkt) p.key;
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
}
instanceof überprüft, ob Objekt zu
Klasse gehört
21
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
if (p.key instanceof Punkt) {
Punkt myPunkt = (Punkt) p.key;
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
}
Ausgabe: 1.0 0.0
2.0 2.0 ...es werden nur die
0.0 1.0 Punkte ausgegeben
22
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
//gib Ergebnis von p.key.toString() aus:
System.out.println(p.key);
}
}
}
Ausgabe:
4
3.2
Punkt@c3c749
Punkt@150bd4d
Punkt@1bc4459
23
Liste für Objekte
java.lang.Object
+toString():String
java.lang.Double
java.lang.Integer
+toString():String
+toString():String
Punkt
for (ListenElement p = l.head; p != null; p = p.next) {
//gib Ergebnis von p.key.toString() aus:
System.out.println(p.key);
}
Ausgabe:
4
3.2
Punkt@c3c749
Punkt@150bd4d
Punkt@1bc4459
toString (Klasse Integer)
toString (Klasse Double)
toString (Klasse Object)
24
Liste für Objekte
java.lang.Object
+toString():String
java.lang.Double
java.lang.Integer
Punkt
+toString():String
+toString():String
+toString():String
public class Punkt {
public double x;
public double y;
public String toString() {
return "(" + x + ", " + y + ")";
}
//...
}
Methode toString
der Klasse Object
wird überschrieben
25
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
//gib Ergebnis von p.key.toString() aus:
System.out.println(p.key);
}
java.lang.Object
}
}
Ausgabe:
4
3.2
(1.0, 0.0)
(2.0, 2.0)
(0.0, 1.0)
+toString():String
Punkt
26
+toString():String
Übersicht
InsertionSort
• für Punkte
Einschub: Liste für Objekte beliebiger Klassen
• für Objekte beliebiger Klassen
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
27
InsertionSort für Objekte
public class Sortierverfahren {
public static void insertionSort(Punkt[] a) {
for (int j = 1; j < a.length; j++) {
Punkt key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
28
InsertionSort für Objekte
public class Sortierverfahren {
public static void insertionSort(Object[] a) {
for (int j = 1; j < a.length; j++) {
Object key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
Compiler: "The method
}
a[i + 1] = key;
compareTo(Object) is undefined for
}
the type Object"
}
}
29
InsertionSort für Objekte
public class Sortierverfahren {
public static void insertionSort(Comparable[] a) {
for (int j = 1; j < a.length; j++) {
Comparable key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key; To Do:
}
Definiere Klasse Comparable,
}
so dass sichergestellt ist, dass
}
Objekte von Unterklassen
vergleichbar sind
30
InsertionSort für Objekte
public abstract class Comparable {
public abstract int compareTo(Object o);
}
Es fällt uns schwer, eine allgemeine
Definition zu finden.
Wir sollten daher verbieten, Instanzen
unserer Klasse Comparable zu erzeugen.
Deshalb:
abstract
31
InsertionSort für Objekte
public abstract class Comparable {
public abstract int compareTo(Object o);
}
Die Klasse unserer Vergleichsobjekte
hat evtl. bereits eine Oberklasse.
Comparable
Tier
Elefant
Mehrfachvererbung ist
verboten!
32
InsertionSort für Objekte
public interface Comparable {
public int compareTo(Object o);
}
Die Klasse unserer Vergleichsobjekte
hat evtl. bereits eine Oberklasse.
Deshalb:
interface
<<Interface>>
Comparable
Tier
Elefant
33
InsertionSort für Objekte
Interfaces ähneln abstrakten Klassen, die ausschließlich
abstrakte Methoden besitzen
(keine Attribute und keine implementierten Methoden).
Unterschied:
Eine Klasse kann mehrere Interfaces implementieren,
aber nur eine Klasse (direkt) erweitern.
<<Interface>>
Comparable
Tier
Elefant
34
InsertionSort für Objekte
public interface Comparable {
public int compareTo(Object o);
}
Interface Comparable
war bis Java-Version 1.4
so im Paket java.lang definiert.
35
InsertionSort für Objekte
public class Punkt {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
36
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
Compiler: "The type Punkt must
public Punkt(double myX, double myY) {
implement the inherited abstract
x = myX;
method Comparable.compareTo(Object)"
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
37
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Object o) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
38
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4]; Hier wird Feld mit
a[0] = new Punkt(1, 2);
Punkt-Objekten übergeben
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
Hier wird Feld mit
a[3] = new Punkt(4, 3);
Comparable-Objekten
insertionSort(a);
entgegengenommen
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static void insertionSort(Comparable[] a) {
//...
}
}
39
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
Ausgabe:
1.0 1.0
for (int i = 0; i < a.length; i++)
2.0
System.out.println(a[i].x + 1.0
" " + a[i].y);
}
3.0
1.0
public static void insertionSort(Comparable[] a) {
//...
4.0 3.0
}
}
40
InsertionSort für Objekte
GeoFigur
+m:Punkt
+GeoFigur(Punkt)
+getFlaeche():double
+compareTo(GeoFigur):int
Quadrat
Kreis
-a:double
-r:double
+Quadrat(Punkt, double)
+getFlaeche():double
+setA(double)
+getA():double
+Kreis(Punkt, double)
+getFlaeche():double
+setR(double)
41
+getR():double
InsertionSort für Objekte
<<Interface>>
Comparable
+compareTo(Object):int
GeoFigur
+m:Punkt
+GeoFigur(Punkt)
+getFlaeche():double
+compareTo(Object):int
Quadrat
Kreis
-a:double
-r:double
+Quadrat(Punkt, double)
+getFlaeche():double
+setA(double)
+getA():double
+Kreis(Punkt, double)
+getFlaeche():double
+setR(double)
42
+getR():double
InsertionSort für Objekte
Klasse GeoFigur in Java:
public abstract class GeoFigur {
public Punkt m;
public GeoFigur(Punkt myM) {
m = myM;
}
public abstract double getFlaeche();
public int compareTo(GeoFigur key) {
if (this.getFlaeche() > key.getFlaeche())
return 1;
if (this.getFlaeche() < key.getFlaeche())
return -1;
return 0;
}
}
43
InsertionSort für Objekte
Klasse GeoFigur in Java:
public abstract class GeoFigur implements Comparable {
public Punkt m;
public GeoFigur(Punkt myM) {
m = myM;
}
public abstract double getFlaeche();
public int compareTo(Object o) {
GeoFigur key = (GeoFigur) o;
if (this.getFlaeche() > key.getFlaeche())
return 1;
if (this.getFlaeche() < key.getFlaeche())
return -1;
return 0;
}
}
44
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
GeoFigur[] a = new GeoFigur[4];
a[0] = new Quadrat(new Punkt(0.0, 0.0), 2.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].getClass().toString()
+ " " + a[i].getFlaeche());
}
public static void insertionSort(Comparable[] a) {
//...
}
}
45
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
GeoFigur[] a = new GeoFigur[4];
a[0] = new Quadrat(new Punkt(0.0, 0.0), 2.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
Ausgabe:
for (int i = 0; i < a.length; i++)
System.out.println(a[i].getClass().toString()
+ " " + a[i].getFlaeche());
class Quadrat 4.0
class
Kreis 12.566370614359172
}
public static void insertionSort(Comparable[] a) {
class
//... Quadrat 16.0
}
class
Kreis 50.26548245743669
}
46
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
Compiler:
Type mismatch:
cannot convert
from Punkt to
GeoFigur
GeoFigur[] a = new GeoFigur[4];
a[0] = new Punkt(0.0, 0.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].getClass().toString()
+ " " + a[i].getFlaeche());
}
public static void insertionSort(Comparable[] a) {
//...
}
}
47
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
Comparable[] a = new Comparable[4];
a[0] = new Punkt(0.0, 0.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
public static void insertionSort(Comparable[] a) {
//...
}
}
48
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
Comparable[] a = new Comparable[4];
a[0] = new Punkt(0.0, 0.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
Ausgabe: for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
Exception in thread "main" java.lang.ClassCastException:
}
Quadrat cannot be cast to Punkt
public static void insertionSort(Comparable[] a) {
at Punkt.compareTo(Punkt.java:12)
//...
at Sortierverfahren.insertionSort(Sortierverfahren.java:21)
}
at
} Sortierverfahren.main(Sortierverfahren.java:9)
49
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Object o) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
Ausgabe:
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y
== p.y)
return
0;
Exception
in thread
"main"
java.lang.ClassCastException:
}
Quadrat
cannot be cast to Punkt
return 1;
at Punkt.compareTo(Punkt.java:12)
at} Sortierverfahren.insertionSort(Sortierverfahren.java:21)
}at Sortierverfahren.main(Sortierverfahren.java:9)
50
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
public int compareTo(Object o) {
if (o instanceof Punkt) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
} else {
//?
}
}
}
51
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
public int compareTo(Object o) {
if (o instanceof Punkt) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
} else {
//?
}
}
}
Es wäre schön, wenn wir
wüssten, mit was für Objekten
wir zu rechnen haben.
52
Übersicht
InsertionSort
Einschub
• für Punkte (Wiederholung vom 19.12.2013)
• für Objekte beliebiger Klassen
Einschub: Liste für Objekte von Klassen,
die ein(e) Nutzer(in) festlegen kann
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
53
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
Wir möchten es
verbieten!
for (ListenElement p = l.head; p != null; p = p.next) {
//gib Ergebnis von p.key.toString() aus:
System.out.println(p.key);
}
}
}
Wie kann man der Liste „sagen“,
dass nur Objekte einer bestimmten
Klasse erlaubt sind?
54
Liste für Objekte
public class Liste {
public ListenElement head;
public ListenElement insert(Object k) {
ListenElement x = new ListenElement(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class ListenElement {
public Object key;
public ListenElement prev;
public ListenElement next;
public ListenElement(Object k, ListenElement p) {
key = k;
next = p;
prev = null;
}
}
55
Liste für Objekte
Seit Java Version 5 können
generische Datentypen
definiert werden.
Platzhalter für
den Namen einer
Klasse
public class ListItem<T> {
public Object key;
public ListenElement prev;
public ListenElement next;
public ListenElement(Object k, ListenElement p) {
key = k;
next = p;
prev = null;
}
}
56
Liste für Objekte
ListItem<T> kann nur
Objekte vom Typ T
speichern.
public class ListItem<T> {
public T key;
public ListItem<T> prev;
public ListItem<T> next;
public ListItem (T k, ListItem<T> p) {
key = k;
next = p;
prev = null;
}
}
57
Liste für Objekte
public class List<T> {
public ListItem<T> head;
public ListItem<T> insert(T k) {
ListItem<T> x = new ListItem<T>(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class ListItem<T> {
public T key;
public ListItem<T> prev;
public ListItem<T> next;
public ListItem (T k, ListItem<T> p) {
key = k;
next = p;
prev = null;
}
}
List<T> erlaubt nur
Objekte vom Typ T!
58
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Punkt> l = new List<Punkt>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
public class List<T> {
…
}
Platzhalter wird durch Klassennamen ersetzt
for (ListItem<Punkt> p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
59
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Punkt> l = new List<Punkt>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListItem<Punkt> p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Ausgabe: 1.0 0.0
2.0 2.0
0.0 1.0
60
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Punkt> l = new List<Punkt>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(2.0));
for (ListItem<Punkt> p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Compiler:
"The method insert(Punkt) in
the type List<Punkt> is not applicable
for the arguments (Double)"
61
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Object> l = new List<Object>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(2.0));
for (ListItem<Object> p = l.head; p != null; p = p.next) {
System.out.println(p.key);
}
}
}
Ausgabe:
2.0
(1.0, 0.0)
(2.0, 2.0)
(0.0, 1.0)
62
Übersicht
InsertionSort
• für Punkte
• für Objekte beliebiger Klassen
Einschub: Liste für Objekte von Klassen,
die ein(e) Nutzer(in) festlegen kann
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
63
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
public int compareTo(Object o) {
if (o instanceof Punkt) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
} else {
//?
}
}
}
Es wäre schön, wenn wir
wüssten, mit was für Objekten
wir zu rechnen haben.
64
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
65
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
public class Punkt implements Comparable {
//...
public int compareTo(Object o) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
66
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
public class Punkt implements Comparable<Punkt> {
//...
public int compareTo(Punkt p) {
}
}
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
Punkte können nur mit Punkten
verglichen werden!
67
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static void insertionSort(Comparable[] a) {
//...
}
}
68
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static <T> void insertionSort (T[] a) {
//...
}
}
69
InsertionSort für Objekte
generische Methode:
Nimmt Feld mit Objekten vom
Typ T entgegen.
Platzhalter
public static <T> void insertionSort (T[] a) {
//...
}
}
70
InsertionSort für Objekte
generische Methode:
Wie sicherstellen, dass T das
Interface Comparable<T>
implementiert?
Platzhalter
public static <T> void insertionSort (T[] a) {
//...
}
}
71
InsertionSort für Objekte
generische Methode:
Gib entsprechende Bedingung an!
public static <T extends Comparable<T>> void
insertionSort (T[] a) {
//...
}
}
72
InsertionSort für Objekte
generische Methode:
public class Punkt implements Comparable<Punkt> {
//...
Achtung: Schlüsselwort ist „extends“ und
nicht „implements“!
public static <T extends Comparable<T>> void
insertionSort (T[] a) {
//...
}
}
73
InsertionSort für Objekte
public class Sortierverfahren {
public static <T extends Comparable<T>> void
insertionSort(T[] a) {
for (int j = 1; j < a.length; j++) {
T key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
74
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static <T extends Comparable<T>> void
insertionSort (T[] a) {
//...
}
75
Schluss
Generische Datentypen/Methoden
erlauben es,
Datenstrukturen/Algorithmen
so zu implementieren,
dass sie für verschiedene Datentypen angewandt
werden können.
76
Übersicht
InsertionSort
• für Punkte
• für Objekte beliebiger Klassen
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
Beispiel: Mehrere Interfaces
77
Mehrfachvererbung
Tier
+masse:double
+volumen:double
masse in kg,
volumen in m3
Landtier
Wassertier
+getGewichtskraft():double
+getAuftrieb():double
Frosch
Quelle: Wikipedia
In Java ist Mehrfachvererbung verboten!
??
Quelle: Wikipedia
Quelle: Wikipedia 78
Mehrere Interfaces
Tier
+masse:double
+volumen:double
<<Interface>>
Landtier
+getGewichtskraft():double
Frosch
<<Interface>>
Wassertier
!
+getAuftrieb():double
+getGewichtskraft():double
Quelle: Wikipedia
+getAuftrieb():double
Quelle: Wikipedia
public class Frosch extends Tier implements Landtier, Wassertier {
//...
79
Mehrere Interfaces und Generics
public class Frosch<T,K,V> extends Tier<T> implements
Landtier<T,V>, Wassertier<K> {
//...
oO
Quelle: Wikipedia
80
Herunterladen