C, die ein Interface I implementiert, bildet einen Subtyp von I// Interface-Deklaration
interface Foo {
static final int QUUX = 42;
void foo();
}
// Implementierung
class Bar implements Foo, Baz {
@Override
public void foo() { ... }
}
Foo f = new Bar();
interface I {
void foo();
}
interface J extends I, K {
void bar();
}
WS 12/13, ÜB 5
Aufgabe A.1
Die Idee dahinter ist, zusätzliche Variablen für Typen einzuführen. Diese Typ-Variablen repräsentieren zum Zeitpunkt der Implementierung unbekannte Typen. Erst bei der Verwendung der Klassen, Schnittstellen und Methoden werden diese Typ-Variablen durch konkrete Typen ersetzt.
Code von Container-Datentypen (und anderen Datenstrukturen) ist unabhängig vom Typ der Basisdaten
interface Foo<T> { ... }
class Bar<T> { ... }
class Baz implements Foo<Integer> { ... }
class Quux<T, U> implements Foo<T> { ... }
// Example
Bar<Integer> b = new Bar<Integer>();
// Ab Java 7 (Diamond operator)
Bar<Integer> b = new Bar<>();
// T muss vom Typ Bar sein
class Foo<T extends Bar> { ... }
// T muss von den Typen Bar, Baz und Quux sein
class Foo<T extends Bar & Baz & Quux> { ... }
public class GenericMethods {
public static <T> T random(T m, T n) {
return Math.random() > 0.5 ? m : n;
}
public static <T> T random(List<T> list) {
return list.get(Math.round(Math.random() * (list.size - 1)));
}
}
// Not OK
List<Object> foos = new ArrayList<Foo>();
// OK
List<Foo> foos = new ArrayList<>();
List<?> foos = new ArrayList<Foo>();
List<? extends Foo> foos = new ArrayList<Foo>();
? kann als Wildcard verwendet werdenpublic static T max(T x, T y) {
return x > y ? x : y;
}
public static void print(List<? extends Number> list) {
for (Number n : list)
System.out.print(n + " ");
System.out.println();
}
Nein, Ja
class Shape { /* ... */ }
class Circle extends Shape { /* ... */ }
class Rectangle extends Shape { /* ... */ }
class Node<T> { /* ... */ }
Node<Circle> nc = new Node<>();
Node<Shape> ns = nc;
class Node<T> implements Comparable<T> {
// ...
public int compareTo(T obj) { /* ... */ }
}
Node<String> node = new Node<>();
Comparable<String> comp = node;
Nein, Ja

Eine Methode f heißt rekursiv, wenn im Rumpf von f Aufrufe von f vorkommen.
public static long fac(final int n) {
if (n < 2) {
return 1;
} else {
return n * fac(n - 1);
}
}
// Und das Ganze nochmal kürzer
public static long fac(final int n) {
return (n < 2) ? 1 : n * fac(n - 1);
}
Implementiert binäre Suche auf einem int-Array rekursiv
