Einführung in die Programmierung mit Java Teil 15: Wiederholung Martin Hofmann Steffen Jost LFE Theoretische Informatik, Institut für Informatik, Ludwig-Maximilians Universität, München 3. Februar 2016 Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-578
Inhalt Teil 15: Wiederholung 1 UML 2 Vererbung 3 Nebenläufigkeit 4 Streams Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-579
UML Wiederholung UML Vererbung Nebenläufigkeit Streams UML-Diagramme werden primär als Strukturierungs- und Modellierunsmittel dem Weg von der informellen Beschreibung zum fertigen Programm eingesetzt. Welche Komponenten gibt es? Was leistet jede Komponente? Wie interagieren die Komponenten? Welche Abhängigkeiten gibt es? Modellierung beinhaltet auch Abstraktion: Wenn z.b. ein Konstruktor nicht aufgelistet wird, dann kann man darauf schließen, dass dessen Verhalten gewöhnlich ist; ansonsten gibt es wohl Besonderheiten zu beachten. Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-580
UML Klassendiagramm Jedes Objekt durch Box mit drei Teilen repräsentiert: 1 Klassenname 2 Attribute (=Instanzvariablen) 3 Methoden (meist nur public) Pfeile von Unterklasse zu Oberklasse von Klasse zu implementierte Schnittstelle benutzt -Beziehung, z.b. Aufruf von Methoden Aggregation: hat-ein als Instanzvariable Komposition: ist-teil-von, bedeutet meist das Lebensspanne durch Element an Spitze bestimmt wird, z.b. Glied MyLinkedList Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-581
Beispiel: UML Klassendiagramm I Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-582
Beispiel: UML Klassendiagramm II Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-583
UML Speicherdiagramm Diagramm zeigt alle vorhandenen Objekte im Speicher, und meistens noch alle lokale Variablen mit Inhalt. Jedes Objekt durch Box mit zwei Teilen repräsentiert: 1 Klassenname Falls lokale Variablen nicht separat angegeben werden, wird im Boxtitel oft der lokale Bezeichner dem Klassennamen mit : vorangestellt. 2 Attribute (=Instanzvariablen) mit aktuellem Inhalt Nur eine Sorte Pfeile für Referenzen, also Verweise auf andere Objekte... wird in ähnlicher Form auch als Objektdiagramm bezeichnet. Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-584
Beispiel: UML Speicherdiagramm I Lokale Variablen kerzen = rotekerze = grünekerze= baum = deko = Speicher Weihnachtsbaum lichterkette = kugeln = 7 ArrayList<Kerze> [0] = [1] = ArrayList<Kerze> [0] = [1] = [2] = Kerze brennt=true Kerze brennt=false Kerze brennt=false Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-585
Beispiel: UML Speicherdiagramm II Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-586
Zusammenfassung Vererbung Private Instanzvariablen sind weiter vorhanden, aber unsichtbar! Konsequenz: Zugriff auf geerbte Instanzvariablen nur über geerbte Methoden Alle geerbten Methoden weiterhin unverändert sichtbar. Geerbte Methoden können überschrieben werden. Überschriebene Methoden ersetzen ursprüngliche Definition überall, auch wenn das Objekt über Subtyping als Ahne aufgefasst wird. Falle: Ohne Override kann es zu versehentlichen Überladen kommen insbesondere ist es es kein Überschreiben, wenn Argumente spezialisiert werden! Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-587
Aufgabe Vererbung Welche Ausgabe wird erzeugt? A a = new A(3); B b = new B(4); a.ausgabe(a); a.ausgabe(b); b.ausgabe(a); b.ausgabe(b); public class A { public int x; public A(int x) { this.x=x; } public int getx() { return x;} public void ausgabe(a a) { System.out.println( "A "+ x + " "+ a.getx()); } } public class B extends A { public B(int x) { super(x); } public int getx() { return (3 * super.getx()); } } Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-588
Aufgabe Vererbung Welche Ausgabe wird erzeugt? A a = new A(3); B b = new B(4); a.ausgabe(a); a.ausgabe(b); b.ausgabe(a); b.ausgabe(b); Antwort: public class A { public int x; public A(int x) { this.x=x; } public int getx() { return x;} public void ausgabe(a a) { System.out.println( "A "+ x + " "+ a.getx()); } } A 3 3 A 3 12 A 4 3 A 4 12 public class B extends A { public B(int x) { super(x); } public int getx() { return (3 * super.getx()); } } Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-588
Nebenläufigkeit Grundsätzliche Fragestellung für Synchronisation: Was passiert, wenn ich hier unterbrochen werde und sich ggf. Instanzvariablen ändern? Meist ein Problem, wenn Instanzvariablen gelesen, verändert und zurückgeschrieben werden; insbesondere bei mehreren Instanzvariablen. Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-589
Probleme bei Nebenläufigkeit Bei nebenläufigen Berechnungen mit mehreren Threads können u.a. folgende Probleme auftreten: Race-Condition Das Ergebnis der Berechnung hängt von der Verzahnung der Threads ab. Deadlock Ein Thread wartet auf das Ergebnis eines anderen Threads, welche direkt oder indirekt selbst auf das Ergebnis des ersten Threads wartet. Beide warten aufeinander, die Berechnung kommt somit zum erliegen. Durch den Einsatz von Synchronisation/Locks kann man Race-Conditions vermeiden, erhöht aber prinzipiell die Gefahr von Deadlocks. Verschiedene Threads können sich gegenseitig beeinflussen. Manchmal wird ein Thread schneller als ein anderer abgehandelt. Da die Möglichkeiten der Verzahnung immens sind, ist das Gesamtergebnis der Berechnung kaum vorhersagbar/testbar. Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-590
Beispiel: H11-1 Aufgabe H11-1 könnte man mit Streams direkt und ohne Hilfsdefinition einfacher lösen: List<Boolean> result = xs.stream().map(x -> 3*x).map(x -> x%2==0).collect(collectors.tolist()); System.out.println(result.toString()); Der Punkt ist der gewöhnliche Methoden-Zugriff, d.h. man kann ganz genauso schreiben: System.out.println(xs.stream().map(x -> 4*x).collect(Collectors.toList())); xs.stream().map(x -> x%2==0).foreach( y -> System.out.print(y+", ")); Martin Hofmann, Steffen Jost Einführung in die Programmierung Wiederholung 15-591