Aufrufe von Objektmethoden SWE-35 Objektmethoden werden für ein bestimmtes Objekt aufgerufen; sie benutzen dessen Objektvariablen: double r = big.getradius (); Methodenaufrufe können auch die Werte von Objektvariablen (den Objektzustand) verändern: small.move (1, 2); Schnittstelle der Klasse: von außen aufrufbare Methoden: getx, gety, getradius, move, grow, Konstruktor Circles Der Zugriff von außen auf Objektvariable kann durch Modifizierer private verboten werden, d. h. small.radius = 2.3; ist nicht erlaubt. class Circles { int getx () { return x; int gety () { return y; double getradius () { return radius; void move (int dx, int dy) { x += dx; y += dy; void grow (double dr) { radius += dr; Circles (int ix, int iy, double ir) { x = ix; y = iy; radius = ir; private int x, y; private double radius; Vorlesung Software-Entwicklung / Folie 35 Methodenaufrufe für Objekte verstehen Erläuterungen am Beispiel einer gesamten Klassendefinition nachlesen: Judy Bishop: Java lernen, 3.Aufl., Abschnitt 3.4, 3.5 Was gehört zur Schnittstelle einer Klasse, was zu ihrer Implementierung?
Beispiel für den Entwurf einer Klasse SWE-36 Aufgabe: Eine Klasse, zu der man Stempel als Objekte erzeugen kann. Ein Stempel soll Wertmarken bestimmter Größe aber mit unterschiedlichen Preisen drucken können. (siehe SWE-34) class Stamps { Stamps (int w, int d) private void aline(char price) {width = w; depth = d; { System.out.print (border); for (int i=2; i<width; i++) void aticket (char price) System.out.print (price); { aline (border); System.out.println (border); for (int i=2; i<depth; i++) aline (price); aline (border); private int width, depth; private static final char border = '='; // Stamps Variable für Stempel verschiedener Größe und ihre Benutzung: 2001 bei Prof. Dr. Uwe Kastens Stamps small = new Stamps(4,4); ein 4x4-Stempel small.aticket('1'); eine 1-er-Marke drucken Stamps big = new Stamps(7,7); ein 7x7-Stempel big.aticket('5'); big.aticket('8'); 5er- und 8er-Marken Drucken Vorlesung Software-Entwicklung / Folie 36 Entwurfsaspekte am Beispiel lernen Erläuterungen dazu Vergleich der Datenabstraktion hier zur funktionalen Abstraktion auf Folie 34 nachlesen: Judy Bishop: Java lernen, 3.Aufl., Abschnitt 5.1 Ist der Zustand der Stempelobjekte veränderbar? Begründung.
Rekursion SWE-37 aus: Bauer, Goos: Informatik, Erster Teil, Dritte Auflage, Springer-Verlag 1982, S. 52 Mächtiges, einfaches, elegantes Prinzip zur Definition von Strukturen, Abläufen, Eigenschaften. Eine Definition verwendet das Definierte, z. B. Programmstrukturen wie Anweisung, Ausdruck, Block, Schachtelung Datenstrukturen wie Listen, Bäume Eigenschaften z. B. Erreichbarkeit in Graphen (Netzen) Problemzerlegung, die auf das Ausgangsproblem mit verkleinerten Werten zurückführt Funktion f, die Aufrufe von f enthält Vorlesung Software-Entwicklung / Folie 37 Rekursion als wichtiges Grundprinzip erkennen Beispiele für rekursive Definitionen Geben Sie rekursive Definitionen an. Geben Sie zu den Beispielen an, ob die Rekursion abbricht. Begründung?
Türme von Hanoi SWE-38 Aufgabe: Einen Turm von A nach C verlegen; dabei nur einzelne Scheiben bewegen. Es darf nie eine größere Scheibe auf einer kleineren liegen. A B C 1 3 2 void hanoi (int höhe, char quelle, char ablage, char ziel) { if (höhe == 1) System.out.println ("lege 1 von "+ quelle + " nach " + ziel); else { hanoi (höhe - 1, quelle, ziel, ablage); System.out.println ("lege "+höhe+" von "+quelle+" nach "+ziel); hanoi (höhe - 1, Ablage, quelle, ziel); Aufruf z. B.: hanoi (4, 'A', 'B', 'C'); Vorlesung Software-Entwicklung / Folie 38 Ein typisch rekursives Verfahren kennenlernen Entwurfsidee Struktur der Rekursion Anzahl der Züge Übungsaufgaben: Vergleichen Sie ein nicht-rekursive Beschreibung des Verfahrens mit der rekursiven. Wieviele Züge benötigt man für einen Turm der Höhe n?
Rekursive Funktionen SWE-39 Die Lösung einer Aufgabe wird auf eine Lösung der gleichen Aufgabe mit verkleinerten Parametern zurückgeführt. Eine Funktion F ist direkt rekursiv, wenn sie einen Aufruf von F enthält; indirekt rekursiv, wenn ein Aufruf von F über Aufrufe anderer Funktionen wieder zu einem Aufruf von F führen kann. Beispiel GGT als rekursive Funktion: int ggt (int a, int b) { if (a!= b) { if (a > b) return ggt (a - b, b); Das Ergebnis des rekursiven Aufrufs wird else return ggt (a, b - a); als Ergebnis dieses Aufrufs zurückgegeben. else return a; Vorlesung Software-Entwicklung / Folie 39 Konzept "Rekursive Funktion" am Beispiel Ggt. Erläuterungen dazu; Terminierung Erläutern Sie die Ausführung einer der return-anweisungen.
Lebensdauer von Variablen, Laufzeitkeller SWE-40 Lebensdauer: Zeit der Programmausführung von der Bildung (Allokation) bis zur Vernichtung (Deallokation) einer Variablen im Speicher. Klassenvariable: Parameter und lokale Variable: Objektvariable: die gesamte Programmausführung die Ausführung eines Aufrufes der Funktion während der Existenz des Objektes Beispiel SWE-34 ggt rekursiv Laufzeitkeller: Für die Ausführung eines Aufrufes wird ein Speicherblock mit den Parametern und lokalen Variablen gebildet (Schachtel). Bei Beginn eines Aufrufes wird eine Schachtel auf dem Laufzeitkeller gekellert, am Ende wieder entkellert. args width depth c i width c i 7 6 '5' 3 6 '5' 4 main aticket aline args Erg. a b Erg. a b Erg. a b 54 36 18 36 18 18 main ggt ggt ggt Vorlesung Software-Entwicklung / Folie 40 Allgemeine Konzepte Lebensdauer und Laufzeitkeller verstehen Erläuterungen an Beispielen nachlesen: GdP-40, GdP-41 Übungsaufgaben: Schreiben Sie rekursive Funktionen als Java-Programme. Lassen Sie Werte von Parametern und lokalen Variablen am Anfang und am Ende der Aufrufe ausgeben.
Rekursive Datenstrukturen mit rekursiven Methoden Ein binärer Baum ist leer oder er besteht aus einem Wert und zwei Unterbäumen: class BinTree // Binäre Bäume mit Zeichenwerten an den Baumknoten { BinTree (BinTree l, char v, BinTree r) // Konstruktor für innere Knoten { left = l; value = v; right = r; BinTree (char v) // Konstruktor für Blattknoten { left = null; value = v; right = null; void infix () // Ausgabe in Infix-Form, geklammert { System.out.print ('('); if (left!= null) left.infix (); System.out.print (value); if (right!= null) right.infix (); System.out.print (')'); void postfix () // Ausgabe in Postfix-Form { if (left!= null) left.postfix (); if (right!= null) right.postfix (); System.out.print (value); private BinTree left, right; private char value; SWE-41 Aufruf z.b.: (new BinTree(new BinTree('A'),'/',new BinTree('B'))).inFix(); Rekursiv definierte Datenstrukturen kennenlernen Erläuterung der Begriffe Vorlesung Software-Entwicklung / Folie 41 Erläuterung der Begriffe Binärbaum, infix, präfix, postfix Umgang mit rekursiven Methoden auf rekursiven Datenstrukturen Übungsaufgaben: Zeigen Sie, daß die Datenstruktur und ihre Methoden zum Durchlaufen (infix, präfix, postfix) die gleiche Rekursionsstruktur haben.