Objektorientierte Programmierung
LVA 185.162, VL 2.0, 2010 W
| Ausgabe: | 03.11.2010 |
| reguläre Abgabe: | 10.11.2010, 13:45 Uhr |
| nachträgliche Abgabe: | 17.11.2010, 13:45 Uhr |
public interface Pretty {
// "transform" transforms a piece of Java
// source code into equivalent code with
// (possibly) prettier formatting.
// "transform(x)+transform(y)" shall return
// the same string as "transform(x+y)" for
// all strings x and y.
String transform (String s);
// "reset" indicates the end of source code.
// The internal state is reset (if there is
// one), and the argument of the next
// invocation of transform represents the
// begin of another source code.
void reset();
}
Es sollen folgende Typen (also Klassen, abstrakte Klassen oder Interfaces) als Untertypen von Pretty erstellt und implementiert werden:
class A{ B c; ;D f { c.f(d) /*x*/; /*y*/} }
in folgenden Code:
class A
{
B c;
;
D f
{
c.f(d) /*x*/;
/*y*/
}
}
Zur genaueren Beschreibung brauchen wir den ganzzahligen Parameter depth, der im Konstruktor auf einen Wert größer 0 gesetzt wird, und eine ganzzahlige Variable pos:
;(Strichpunkt) beginnt eine neue Zeile.
class A{
B c;
;
D f {
c.f(d) /*x*/;
/*y*/
}
}
Gehen Sie zur Vereinfachung der Lösung davon aus, dass Kommentare und Strings im Input-String von transform weder Strichpunkte noch geschwungene Klammern enthalten. Es braucht nicht überprüft werden, ob diese Zeichen innerhalb oder außerhalb eines Kommentars oder Strings vorkommen.
Versehen Sie (abstrakte) Klassen und Interfaces mit allen notwendigen Zusicherungen (entsprechend obigen Beschreibungen) und stellen Sie sicher, dass Sie nur dort eine Vererbungsbeziehung (extends oder implements) verwenden, wo tatsächlich eine Untertypbeziehung (auch hinsichtlich der Zusicherungen) besteht. Zwischen je zwei Untertypen von Pretty soll eine Untertypbeziehung bestehen, wenn dies aufgrund der Schnittstellen und Zusicherungen möglich ist.
Schreiben Sie so wenig Programmcode wie möglich. Sie können so viele zusätzliche (abstrakte) Klassen und Interfaces unterhalb von Pretty einführen, wie Sie für die Wiederverwendung von Code als vorteilhaft erachten.
Schreiben Sie eine Klasse Test zum Testen Ihrer Lösung. Überprüfen Sie so gut Sie können mittels Testfällen, ob dort, wo Sie eine Untertypbeziehung annehmen, Ersetzbarkeit gegeben ist. Wenn zwischen zwei der oben beschriebenen Typen keine Untertypbeziehung besteht, geben Sie in einem Kommentar in der Testklasse ein kurzes Beispiel an, in dem die Ersetztbarkeit verletzt ist.
Eine Grundlage für das Auffinden der Untertypbeziehungen sind gute Zusicherungen. Die wesentlichen Zusicherungen kommen bereits in obigen Beschreibungen der benötigten Typen vor. Sie brauchen die einzelnen Beschreibungsteile nur mehr den richtigen Zusicherungsarten in den entsprechenden Teilen der Typen zuzuordnen. Untertypbeziehungen ergeben sich aus den erlaubten Beziehungen zwischen Zusicherungen in Unter- und Obertypen. Es hat sich als günstig erwiesen, alle Zusicherungen, die in einem Obertyp gelten, im Untertyp direkt bei den betroffenen Methoden nochmals hinzuschreiben, da sie sonst leicht übersehen werden.
Vergewissern Sie sich der Korrektheit der Untertypbeziehungen zusätzlich über geeignete Testfälle. Die Anzahl der Testfälle ist nicht entscheidend, wohl aber deren Qualität: Es kommt darauf an, dass die Testfälle mögliche Verletzungen der Ersetzbarkeit aufdecken können. Beispielsweise muss überprüft werden, ob transform auch nach Ersetzungen und anderen Methodenaufrufen das zurückgibt, was erwartet wird. Umgekehrt sollen Sie sich auch vergewissern, dass Sie keine Gelegenheit für Untertypbeziehungen verpasst haben, indem Sie Beispiele dafür finden, wie angenommene Untertypbeziehungen das Ersetzbarkeitsprinzip verletzen würden. Schreiben Sie die Gegenbeispiele als Kommentare neben den Testfällen für Ersetzbarkeit in die Testklasse.
Zusicherungen in Testklassen werden aus praktischen Überlegungen bei der Beurteilung nicht berücksichtigt. Sorgen Sie aber bitte dafür, dass ein Aufruf von java Test einigermaßen nachvollziehbaren Output generiert.
Zur Lösung dieser Aufgabe müssen Sie Untertypbeziehungen und vor allem den Einfluss von Zusicherungen auf Untertypbeziehungen im Detail verstehen. Holen Sie sich entsprechende Informationen aus Kapitel 2 des Skriptums. Folgende zusätzlichen Informationen könnten hilfreich sein:
Die Vermeidung unnötigen Codes und direkte Codewiederverwendung fließen zwar auch in die Beurteilung ein, aber in bei weitem geringerem Ausmaß als die Ersetzbarkeit. Auf zusätzlich eingeführten (abstrakten) Klassen und Interfaces müssen natürlich auch Untertypbeziehungen gelten, die auf dieselbe Weise zu überprüfen sind wie für vorgegebene Typen. Es ist daher ratsam, solche Zusätze nicht oder nur sparsam einzusetzen, um unnötige mögliche Fehlerquellen zu vermeiden.
Lassen Sie sich von der Form der Beschreibung der benötigten Typen nicht täuschen. Daraus, dass die Beschreibung eines Typs die Beschreibung eines anderen Typs wiederverwendet, folgt noch lange keine Ersetzbarkeit. Generell sind Sie wahrscheinlich auf dem falschen Weg, wenn es den Anschein hat, A könne Untertyp von B und B gleichzeitig Untertyp von A sein, obwohl A und B ungleich sind.
Achten Sie auf richtige Sichtbarkeit. Alle oben beschriebenen Typen und Methoden sollen überall verwendbar sein, die Sichtbarkeit von Implementierungsdetails soll aber eingeschränkt werden.
Nutzen Sie die vorgesehene Zeit bis 10. November zur Lösung der aktuellen Aufgabe, und stellen Sie noch ausstehende Arbeiten an früheren Aufgaben vorübergehend ein. Am 10. November gibt es keine neue Aufgabe, und ab dann haben Sie etwas Zeit, um noch ausstehende Arbeiten entsprechend den Anweisungen Ihrer Tutorin oder Ihres Tutors nachzuholen.
Bitte verwenden Sie in dieser und den folgenden Aufgaben keine Unterverzeichnisse im Abgabeverzeichnis (und damit auch keine Pakete). Das hat mehrere Gründe:
Schreiben Sie nicht mehr als eine Klasse in jede Datei (ausgenommen geschachtelte Klassen), halten Sie sich an übliche Namenskonventionen in Java (Großschreibung für Namen von Klassen und Interfaces, kleine Anfangsbuchstaben für Variablen und Methoden, etc.), und verwenden Sie die Namen, die in der Aufgabenstellung vorgegeben sind.
Damit erhöhen Sie die Lesbarkeit Ihrer Programme ganz wesentlich.
Außerdem können derartige Fehler
zu Punkteverlusten führen.
Lassen Sie vorgegebene Dateien im Abgabeverzeichnis (wie Pretty.java in Gruppe/Aufgabe4) bitte unverändert. Falls Sie Ihre Lösung auf dem eigenen Rechner erstellen, kopieren Sie bitte vorher die vorgegebenen Dateien auf Ihren Rechner, um unterschiedliche Ausgangssituationen zu vermeiden.