Prof. Dr. Stephan Kleuker Hochschule Osnabrück Fakultät Ing.-Wissenschaften und Informatik - Software-Entwicklung - Komponentenbasierte Software-Entwicklung Wintersemester 2012/13 3. Aufgabenblatt Anmerkung: Zentrales Ziel des Aufgabenblatts ist der erste systematische Umgang mit JUnit. Aufgabe 4 (3 Punkte) 42 s= new EndlicherStapel(2) s.push(42) 42 s.push(null) gibt NullPointerException 99 99 42 42 s.push(99) s.push(43) gibt StapelVollException 42 s.pop() ergibt 99 s.pop() ergibt 42 s.pop() gibt StapelLeerException Ein Stapel (Stack) ist eine Datenstruktur, die Objekte eines bestimmten Typs aufnehmen kann. Dabei werden Objekte mit einer Methode push(.) so auf den Stapel gelegt, dass das neues Element immer oben liegt. Mit der Methode pop(.) wird das oberste Element zurückgegeben und vom Stapel gelöscht. Weiterhin ist es sinnvoll, wenn es Methoden istLeer() bzw. istVoll() gibt, mit denen man prüfen kann, ob ein Stapel voll oder leer ist. a) Realisieren Sie eine generische Klasse EndlicherStapel<Typ> für Objekte der Klasse Typ, mit einem Konstruktor, der die mögliche Größe des Stapels als Parameter hat. Nutzen Sie zur Realisierung des Stapels einen Array und informieren Sie sich, welche Lösungsmöglichkeiten es bzgl. generischer Arrays in Java gibt (der Rest der Generics funktioniert besser). b) Realisieren Sie eine Methode push(Typ), mit der ein Typ-Objekt auf den Stapel gelegt wird. Wird versucht, eine null-Referenz auf den Stapel zu legen, soll eine NullPointerException geworfen werden. Wird versucht ein Objekt auf einen vollen Stapel zu legen, soll eine von Ihren neu zu erstellende StapelVollException geworfen werden. c) Realisieren Sie die Methode pop(), die das zuletzt auf den Stapel gelegte Typ-Objekt zurück gibt und vom Stapel löscht. Wird versucht, ein Objekt von einem leeren Stapel zu nehmen, soll eine von Ihren neu zu erstellende StapelLeerException geworfen werden. d) Realisieren Sie die Methoden istVoll() und istLeer() zur Überprüfung des Stapelzustands. e) Schreiben Sie zu allen realisierten Methoden JUnit-Tests, die alle möglichen Ergebnisse testen. Nutzen Sie dazu Tests mit einem leeren, einem vollen und einem „normal“ gefüllten Stack, auf denen Sie jeweils alle Ihre Methoden ausprobieren. Hinweis: Die Methoden push(.) und pop() sollen die Exceptions nur werfen, nicht selber bearbeiten. In den Tests ist zu prüfen, ob die richtigen Exceptions geworfen werden und die Methoden sonst die korrekten Ergebnisse liefern. Aufgabe 5 (5 Punkte) Studierende wurden aufgefordert, eigene Sortieralgorithmen zu implementieren. Um diese flexibel vergleichbar zu machen, wurde ein Interface definiert, dass von den eigenen Sortierklassen realisiert werden soll. Das Interface sieht wie folgt aus und kann generisch beliebige Klassen T sortieren, die das Interface Comparable<T> realisieren. package hilfsklassen; import java.util.List; public interface MeinSortierer <T extends Comparable<T>>{ public List<T> sortieren(List<T> list); } Die Methode sortieren erhält eine Liste übergeben und soll eine sortierte Liste mit den gleichen Objekten zurückgeben, die absteigend sortiert sind. Eine Klasse ohne Implementierung muss damit wie folgt aussehen. Seite 1 von 2 Prof. Dr. Stephan Kleuker Hochschule Osnabrück Fakultät Ing.-Wissenschaften und Informatik - Software-Entwicklung - Komponentenbasierte Software-Entwicklung Wintersemester 2012/13 3. Aufgabenblatt package hilfsklassen; import java.util.ArrayList; import java.util.List; java.util.List; public class Sortierer1<T extends Comparable<T>> implements MeinSortierer<T> { public List<T> sortieren(List<T> list) { // hier sortieren } } Von der Webseite der Lehrveranstaltung können acht Beispielimplementierungen des Interfaces in einem Projekt geladen werden. Mit der Klasse MainSortierer zeigen die Studierenden vermeintlich, dass zumindest einige ihrer Ideen funktionieren. a) Überlegen Sie sich zunächst genau, wie man formalisieren kann, dass eine Liste mit beliebigen Elementen, die geordnet werden können, durch eine Methode geordnet wird. Schreiben Sie diese Kriterien als Text auf. b) Überlegen Sie sich anschaulich verschiedene Szenarien, also anschauliche Äquivalenzklassen, die eine Überprüfung des Sortierverhaltens einer Liste erlauben. Um die Aufgabe einzuschränken, sollten Sie mindestens fünf Szenarien benennen. c) Formulieren Sie die in b) gefundenen Testfälle für die verschiedenen Sortierer als JUnit4-Testfälle. Welche Sortierer scheitern an welchen Testfällen? d) [ohne Punkte, freiwillig] Die meisten der fehlerhaften Sortierer lassen sich recht einfach korrigieren. Führen Sie diese Korrekturen, z. B. in einem eigenen EclipseProjekt, durch und testen Sie diese Lösungen. Hinweise: Außer zu d) müssen Sie nebenbei den genauen Programmcode nicht verstehen. Hilfsreich kann es sein, sich um parametrisierbare Tests zu kümmern. Einige Hinweise können http://home.edvsz.fh-osnabrueck.de/skleuker/SS11_QS/SS11SQ_Teil01_1.pdf (Folien 71-74) entnommen werden (muss nicht genutzt werden). Zur Erinnerung: Um beliebige Objekte in Java sortieren zu können, muss eine Klasse X nur das Interface Comparable, besser Comparable<X> implementieren. Dieses Interfaces beinhaltet eine Methode public int compareTo(X x) die, falls this kleiner als x sein soll, einen beliebigen negativen Wert, für größer einen beliebigen positiven Wert und bei Gleichheit den int-Wert Null zurückliefern muss. Die Methode muss eine Halbordnung definieren, was anschaulich bedeutet, dass für zwei Objekte a und b, nur einer der drei Fälle, a kleiner b, a gleich b, a größer b, gelten darf. Weiterhin muss aus a kleiner b immer b größer a folgen. Für eine Klasse Mitarbeiter mit einer Objektvariablen int id können die Ergänzungen wie folgt aussehen. public class Mitarbeiter implements Serializable, Comparable<Mitarbeiter>{ Comparable<Mitarbeiter>{ //... @Override public int compareTo(Mitarbeiter o) { return o.ido.id-id; } Die Klasse Integer realisiert auch das Interface. Seite 2 von 2