Tutorium 15.04¶
Wiederholung¶
1 interface Flyable {
2 void fly();
3 }
4
5 abstract class Animal {
6 String name;
7
8 Animal(String name) {
9 this.name = name;
10 }
11
12 void eat() {
13 System.out.println(name + " eats");
14 }
15 }
16
17 class Bird extends Animal implements Flyable {
18 Bird(String name) {
19 super(name);
20 }
21
22 @Override
23 public void fly() {
24 System.out.println(name + " flies");
25 }
26 }
Aufgabe 1¶
1??? class DatabaseConnection {
2 void connect() { ... }
3}
Lösung anzeigen
Wenn man verschiedene Datenbanksysteme (MySQL, Postgres..) austauschbar machen möchte -> Interface
Wenn man beispielsweise eine ähnliche Verbindungslogik teilen -> abstrakte Klasse
Aufgabe 2¶
Es gibt 3 Java-Objekte
NutzerRechnungBildAlle sollten speicherbar sein - interface oder abstrakte Klasse?
Lösung anzeigen
Interface - Die Klassen haben keine natürliche Beziehung. Ein Bild ist keine Rechnung,
sie teilen lediglich eine Fähigkeit.
Aufgabe 3¶
Wir haben Hunde-, Katzen- und Vogel-Objekte. Alle Tiere haben eine Namen, sowie ein Alter, des
Weiteren können sie essen und lauteMachen.
Wie sollte man das am besten abbilden - Abstrakte Klasse oder Interface?
Lösung anzeigen
1abstract class Animal {
2 String name;
3 int age; // Instanzvariablen
4
5 Animal(String name, int age) {
6 this.name = name;
7 this.age = age;
8 }
9
10 void eat() {
11 System.out.println(name + " is eating");
12 }
13
14 abstract void makeSound();
15}
Aufgabe 4¶
Wir wollen einen einfachen Rechner mit methoden wie addieren() und subtrahieren() bauen.
Wie würden wir das am besten Umsetzen?
Lösung anzeigen
1 class Calculator { 2 int add(int a, int b) { 3 return a + b; 4 } 5 }
Aufgabe 5¶
Wir haben 3 Objekte Bericht, Bild und Ticket, alle sollen über die Funktionalität drucken verfügen.
Lösung anzeigen
1interface Druckbares { 2 void print(); 3}Klassen haben keinen Bezug zueinander, wieder nur geteilte Funktionalität.
Aufgabe 6¶
Wir haben eine Firma mit drei verschiedenen Angestellten: Vollzeitangestellter, Halbtagsangestellter und Freelancer.
Alle haben einen Namen und eine AngestelltenID - aber eine unterschiedliche Berechnung bezüglich des Lohns.
Lösung anzeigen
1 abstract class Employee { 2 String name; 3 int employeeId; 4 5 Employee(String name, int employeeId) { 6 this.name = name; 7 this.employeeId = employeeId; 8 } 9 10 abstract double calculateSalary(); 11 }
Aufgabe 7¶
Wir haben eine Ente, eine FliegendeFischDrone und einen Rettungsroboter - ein paar können fliegen, ein paar
schwimmen und manche können auch beides.
Lösung anzeigen
1 interface Flyable { 2 void fly(); 3 } 4 5 interface Swimmable { 6 void swim(); 7 }Es sind Fertigkeiten und eine Klasse kann mehrere interfaces implementieren aber nicht mehrere Klassen erben.
1class Duck implements Flyable, Swimmable { 2 public void fly() {} 3 public void swim() {} 4}
Aufgabe 8¶
Wir haben ein Auto, einen Truck und ein Motorrad. Alle haben eine maximale Geschwindigkeit sowie eine Tankgröße sowie
die Funktionalität einer Beschleunigung, die für alle Gefährte gleich ist.
Lösung anzeigen
1 abstract class Vehicle { 2 int speed; 3 int fuel; 4 5 void accelerate() { 6 speed += 10; 7 } 8 9 abstract void move(); 10 }Geteilte Logik, Felder und Bezug zueinander unter den Objekten.
Aufgabe 9¶
Wir haben drei Objekte: EmailNotification, SmsNotification, PushNotification, und alle sollten die
Funktionalität send(String message) verfügen.
Lösung anzeigen
1 interface NotificationSender { 2 void send(String message); 3 } 4 5 default boolean Method() {System.out.println()}
Aufgabe 10¶
Wir haben einen Kreis, ein Rechteck und ein Dreieck. Alle haben eine Farbe und optional die Funktion sich in x oder y
Richtung zu verschieben. Die Flächenberechnung unterscheidet sich natürlich je nach Form.
Lösung anzeigen
1 abstract class Shape { 2 String color; 3 4 Shape(String color) { 5 this.color = color; 6 } 7 8 abstract double area(); 9 }
Array-Sortierung¶
Arrays können in Java ganz schnell wie z.B.
java.util.Arrays.sort(zahlen);java.util.Arrays.sort(stringListe);sortiert werden.
Comparable-Interface¶
Im Hintergrund funktioniert das über das Interface Comparable. Implementiert man dieses
1 public class Ring implements Comparable <Ring> {
2
3 private double durchmesser;
4
5 public Ring(double durchmesser) {
6 this durchmesser = durchmesser;
7 }
8
9 public int compareTo(Ring o) {
10 double durchmesser_tmp = o.durchmesser
11 if (durchmesser < durchmesser_tmp) return -1;
12 if (durchmesser > durchmesser_tmp return 1;
13 else return 0;
14 }
15
16 public String toString() {
17 return "Ring der Größe " + durchmesser;
18 }
19
20 }
Generizität (Generics)¶
In dem Beispiel haben wir zwei Objekte: Ohrring und Socke.
1 public class Ohrring {
2 public String toString() {
3 return "Ohrring";
4 }
5 }
1 public class Socke {
2 public String toString() {
3 return "Socke";
4 }
5 }
Jetzt wollen wir die Socken zusammenlagen, bzw. Paare bilden damit alles zusammenpasst.
Da wir nicht Klassen für OhrringPaar und für SockenPaar schreiben wollen müssen wir generalisieren und
verwenden als Paar-Typ ein Object.
1 public class Paar {
2
3 private Object links, rechts;
4
5 public Paar(Object links, Object rechts) {
6 this.links = links;
7 this.rechts = rechts;
8 }
9
10 public Object getLinks() {
11 return this.links;
12 }
13
14 public String toString() {
15 return "Paar: " + "(" + links + " und " + rechts + ")";
16 }
17
18 }
Damit haben wir eine allgemeine Generizität, die jedoch bei der Kompilierung unbekannt ist und zu Fehlern führen kann, da…
1public static void main(String[] args) {
2 Socke socke = new Socke();
3 Ohrring ohrring = new Ohrring();
4
5 Paar paar = new Paar(socke, ohrring);
6
7 print(paar);
8}
Type-Parameter (Platzhaltervariablen)¶
1 public class Paar<T> {
2
3 private T links, rechts;
4
5 public Paar(T links, T rechts) {
6 this.links = links;
7 this.rechts = rechts;
8 }
9
10 public T getLinks() {
11 return this.links;
12 }
13
14 public String toString() {
15 return "Paar: " + "(" + links + " und " + rechts + ")";
16 }
17 }
1 public static void main(String[] args) {
2 Socke s1 = new Socke();
3 Socke s2 = new Socke();
4
5 Paar<Socke> sockenPaar = new Paar<Socke>(s1, s2);
6 }
Untergruppen¶
extends¶
public class Paar<T extends Schuhe> { ... }
wildcards¶
List<?> dinge;
Bound wildcards¶
List<? extends Schuhe>;
List<? super Schuhe>;
Methoden¶
Wieder aus unserem Paar beispiel..
public static <T> boolean linksGleichRechts(Paar<T> x) {
return x.getLinks().equals(x.getRight());
}
public static void main(String[] args) {
Hose hose = new Hose();
Jeans jeans = new Jeans();
Paar<Hose> paar1 = new Paar<Hose>(hose, jeans);
System.out.println(linksGleichRechts(paar));
}
Wichtig
🚩
Was passiert, wenn man <T> durch eine Wildcard ersetzt <?>?
Lösung anzeigen
1 public static <T> T getLeft(Paar<T> x) { 2 return x.getLinks(); 3 }1 public static ??? getLeft(Paar<?> x) // unmöglichNimm <?> wenn der Typ egal ist - <T> wenn der Typ nicht egal ist!public static <T> boolean sameLeftType(Paar<T> a, Paar<T> b) public static boolean irgendwas(Paar<?> a, Paar<?> b)
1public static <T,S extends T> GenPaar<T> linksPaar(Paar<T> x, Paar<S> y) {
2 return new GenPaar<T>(x.getL(),y.getL());
3}
Übungen¶
Übung 1¶
1Paar<?> p = new Paar<String>("a", "b");
2String s = p.getLinks();
Lösung anzeigen
Das funktioniert nicht, da der Typ des Paars Paar<?> nicht definiert ist.
Übung 2¶
1List<String> temp = new ArrayList<>();
2List<?> list = temp;
3
4temp.add("Hallo");
5list.add("Test");
Lösung anzeigen
temp.add("Hallo") funktioniertlist.add("Test") funktioniert nicht, da nur Sicht auf die Liste aber Typ unbekannt (nicht veränderbar)Übung 3¶
Box<T>?¶ 1class Box {
2 private Object wert;
3
4 public Box(Object wert) {
5 this.wert = wert;
6 }
7
8 public Object getWert() {
9 return wert;
10 }
11}
Box b = new Box("Hallo");
String s = (String) b.getWert();
Lösung anzeigen
Ohne Generics liefert getWert() nur Object. Deshalb braucht man einen Cast.
Dabei kann ein Laufzeitfehler entstehen, wenn der Inhalt nicht zum Cast passt.
Mit Box<T> kennt der Compiler den Typ schon vorher und viele Fehler werden bereits beim Kompilieren erkannt.
Übung 4¶
In eigenen Worten - was bedeutet <T> und warum sind in Paar<Integer> nur Integer-Werte und in Paar<String>
nur String-Werte erlaubt?
<T> in einer Klasse?¶public class Paar<T> {
private T links;
private T rechts;
public Paar(T links, T rechts) {
this.links = links;
this.rechts = rechts;
}
public T getLinks() {
return links;
}
}
Paar<Integer> p1 = new Paar<>(1, 2);
Paar<String> p2 = new Paar<>("A", "B");
Lösung anzeigen
<T> ist ein Platzhalter für einen Typ. Erst beim Erzeugen des Objekts wird festgelegt,
welcher konkrete Typ gemeint ist. Bei Paar<Integer> ist T also Integer, bei Paar<String>
ist T gleich String.
Übung 5¶
<T>?¶public static <T> T gibLinksZurueck(Paar<T> p) {
return p.getLinks();
}
public static T gibLinksZurueck(Paar<T> p)
Lösung anzeigen
Das <T> vor dem Rückgabetyp führt den Typparameter für diese Methode ein. Ohne dieses <T> kennt der Compiler den Namen T an dieser Stelle gar nicht. Die Schreibweise
public static T ...
geht deshalb nicht, wenn T nicht vorher definiert wurde.
Übung 6¶
1List<String> a = new ArrayList<String>();
2List<String> b = new ArrayList<>();
3List<Object> c = new ArrayList<String>();
4List<?> d = new ArrayList<String>();
5Object e = d.get(0);
6String f = d.get(0);
7String g = (String) d.get(0);
Lösung anzeigen
1List<String> a = new ArrayList<String>(); // kompiliert
2List<String> b = new ArrayList<>(); // kompiliert
3List<Object> c = new ArrayList<String>(); // kompiliert nicht
4List<?> d = new ArrayList<String>(); // kompiliert
5Object e = d.get(0); // kompiliert
6String f = d.get(0); // kompiliert nicht
7String g = (String) d.get(0); // kompiliert
Wichtig
List<String> ist nicht automatisch eine List<Object>
bei List<?> ist der Inhalt nur sicher als Object lesbar
ein Cast ist erlaubt, aber riskant
Übung 7¶
1public static <T extends Number> double doppelt(T wert) {
2 return wert.doubleValue() * 2;
3}
1public static <T> double doppelt(T wert)
Lösung anzeigen
Die Methode benutzt doubleValue(). Diese Methode gibt es bei Number und ihren Unterklassen,
aber nicht bei beliebigen Typen. Ohne extends Number könnte auch ein String übergeben werden,
und dann wäre doubleValue() nicht vorhanden.