Objektorientierte Programmiertechniken
LVA 185.A01, VU, 3 ECTS, 2015/2016 W
| Ausgabe: | 04.11.2015 |
| Abgabe: | 11.11.2015, 12:00 Uhr |
Folgendes Interface ist vorgegeben:
public interface Etikett {
int laenge(); // Laenge des Holzstuecks
String datum(); // Datum der letzten Etikettierung
Etikett alt(); // Falls Holzstueck aus anderem Holzstueck
// erzeugt oder mit neuem Etikett versehen: Das ist das
// vorherige Holzstueck bzw. alte Etikett. Sonst null.
}
Folgende Arten von Etiketten sind derzeit vorgesehen:
Rundholz-Etikett versehen.
Neben laenge, datum und alt ist mit staerke der Durchmesser des Holzstücks angegeben.
Die Methode neu kann das Etikett in eines der Art Rundholz (schließt auch Unterarten davon ein) oder Energieholz ändern.
Rundholz ist eine Klasse.
Rundholz-Etiketts ist das Saegerundholz-Etikett.
Damit wird nur rohes (nicht weiter bearbeitetes) Rundholz hoher Qualität und Stärke (mindestens 30 bis 35 cm) versehen.
Die Methode saegen zerlegt ein Sägerundholz in mehrere Teile der Typen Schnittholz und Energieholz; die Etiketten dieser Teile sind der Methode in einem Array als Argument zu übergeben.
Die Methode schaelen sorgt dafür, dass die oberste Schicht entfernt wird und ein gleichmäßig rundes, nicht mehr rohes Holzstück entsteht; das Etikett muss entsprechend geändert werden.
Saegerundholz ist eine Klasse.
Rundholz ist Industrieholz.
Mit diesem Etikett wird rohes Rundholz von minderer Qualität und Stärke versehen.
Dieses Holz wird industriell zu Papier und diversen Holzwerkstoffen (z.B. Holzfaserplatten) verarbeitet.
Jede der beiden Methoden mahlen (zerlegen in Holzmehl) und fasen (zerlegen in dünne Holzfasern oder Späne) sorgt für eine so starke Verkleinerung der Holzteile, dass eine weitere Etikettierung nicht mehr möglich ist.
Auch Industrieholz ist eine Klasse.
Energieholz wird sehr minderwertiges geerntetes Holz, aber auch Abfallholz aus der Sägeindustrie (z.B. Schwarten) versehen.
Aufgrund der häufig unregelmäßigen Form ist die Angabe der Stärke nicht sinnvoll.
Stattdessen wird das grob geschätzte volumen angegeben.
Es gibt die Methode neu zur Änderung des Etiketts in eines der Art Rundholz oder Energieholz.
Die Methode hacken sorgt für eine Zerlegung des Holzes in Hackschnitzel, die nicht etikettiert werden.
Schnittholz wird entlang der Längsachse gesägtes Holz versehen, das mindestens zwei einander gegenüber liegende flache Längsseiten aufweist.
(Die am Rand übrig bleibenden nur an einer Längsseite flachen Schwarten werden dagegen als Energieholz eingestuft.)
Angegeben wird die dicke und breite des Schnittholzes.
Die Methode saegen zerlegt ein Schnittholz in mehrere kleinere Teile der Typen Schnittholz und Energieholz; die Etiketten dieser Teile sind der Methode in einem Array als Argument zu übergeben.
Die Methode neu kann das Etikett nur in eines der Art Schnittholz, Bauholz oder Energieholz ändern.
Vollkantschnittholz versieht man Schnittholz, das an allen Seiten flach ist und saubere Kanten aufweist.
Bauholz-Etikett (Interface oder abstrakte Klasse) versieht man nur gut getrocknetes Holz, das hinsichtlich der statischen Qualität eine Reihe von in Normen vorgeschriebenen Eigenschaften erfüllt.
Je nach Art des Bauholzes gelten unterschiedliche Normen.
BauRundholz versieht man einer Bauholz-Norm entsprechendes gleichmäßig rundes Holz, das durch Schälen aus Sägerundholz gewonnen wurde.
Angegeben wird die staerke des Holzes.
Kantholz versieht man einer anderen Bauholz-Norm entsprechendes Vollkantschnittholz mit einer Dicke von mindestens 4 cm und einer Breite von maximal der dreifachen Dicke.
Brett versieht man einer weiteren Bauholz-Norm entsprechendes Vollkantschnittholz mit einer Dicke von höchstens 4 cm und einer Breite von mindestens 8 cm.
Versehen Sie alle Ihre (abstrakten) Klassen und Interfaces mit den notwendigen Zusicherungen und stellen Sie sicher, dass Sie nur dort eine Vererbungsbeziehung (extends oder implements) verwenden, wo tatsächlich eine Untertypbeziehung auch hinsichtlich der Zusicherungen besteht. Ermöglichen Sie Untertypbeziehungen zwischen allen diesen Typen, außer wenn Untertypbeziehungen den Beschreibungen der Typen widersprechen würden.
Falls zwischen zwei Typen keine Untertypbeziehung besteht, geben Sie in einem Kommentar in der Datei Test.java eine Begründung dafür an. Bitte geben Sie eine textuelle Begründung; auskommentierte Programmzeilen reichen dafür nicht.
Sie können so viele zusätzliche (abstrakte) Klassen und Interfaces einführen, wie Sie als vorteilhaft erachten. Die Typstruktur soll trotzdem möglichst einfach und klein bleiben, wobei jedoch alle oben genannten Typen (mit den vorgegebenen deutschen Namen) vorkommen müssen, auch solche, die Sie vielleicht für nicht nötig erachten.
Schreiben Sie eine Klasse Test zum Testen Ihrer Lösung. Erzeugen Sie Instanzen der oben genannten Klassen. Überprüfen Sie so gut Sie können mittels Testfällen, ob dort, wo Sie eine Untertypbeziehung annehmen, Ersetzbarkeit gegeben ist.
Daneben soll die Klasse Test.java als Kommentar eine kurze, aber verständliche Beschreibung der Aufteilung der Arbeiten auf die einzelnen Gruppenmitglieder enthalten – wer hat was gemacht.
| Untertypbeziehungen richtig erkannt und eingesetzt, fehlende Untertypbeziehungen richtig beschrieben | 50 Punkte |
| Zusicherungen richtig und sinnvoll eingesetzt | 25 Punkte |
| Lösung sinnvoll getestet | 10 Punkte |
| Vollständigkeit der Lösung (so wie in Aufgabenstellung beschrieben) | 15 Punkte |
Obwohl für das Testen der Lösung nur 10 Punkte veranschlagt sind, kann unzureichendes Testen doch zu größerem Punkteverlust führen, wenn dadurch bestehende Mängel nicht rechtzeitig erkannt werden. Auch Mängel in der Funktionalität können einen Verlust von deutlich mehr als 15 Punkten bedeuten, weil diese sehr wahrscheinlich auch aus Fehlern in Untertypbeziehungen und Zusicherungen resultieren.
Die größte Schwierigkeit liegt darin, alle Untertypbeziehungen zu finden und Ersetzbarkeit sicherzustellen. Vererbungsbeziehungen, die nicht gleichzeitig auch Untertypbeziehungen sind, führen zu sehr hohem Punkteverlust. Ebenso gibt es hohe Punkteabzüge für nicht wahrgenommene Gelegenheiten, Untertypbeziehungen zwischen den Untertypen von Etikett herzustellen, sowie für fehlende oder falsche Begründungen für nicht bestehende Untertypbeziehungen. Geeignete Begründungen wären etwa Gegenbeispiele.
Eine Grundlage für das Auffinden der Untertypbeziehungen sind gute Zusicherungen. Wesentliche (aber nicht alle) Zusicherungen kommen in obigen Beschreibungen vor. 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 bei den betroffenen Methoden nochmals hinzuschreiben, da sie sonst leicht übersehen werden.
Vergewissern Sie sich der Korrektheit der Untertypbeziehungen zusätzlich über Testfälle. Die Anzahl der Testfälle ist nicht entscheidend, wohl aber deren Qualität: Testfälle sollen Verletzungen der Ersetzbarkeit aufdecken können. Gegenbeispiele stellen sicher, dass keine Untertypbeziehungen übersehen wurden.
Zusicherungen in Testklassen werden aus praktischen Überlegungen bei der Beurteilung nicht berücksichtigt.
Zur Lösung dieser Aufgabe müssen Sie Untertypbeziehungen und 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:
Lassen Sie sich von der Form der Beschreibung nicht täuschen. Daraus, dass die Beschreibung eines Typs die Beschreibung eines anderen Typs teilweise wiederholt, folgt noch keine Ersetzbarkeit. Sie sind wahrscheinlich auf dem falschen Weg, wenn es den Anschein hat, A könne Untertyp von B und B gleichzeitig Untertyp von A sein – außer wenn A und B gleich sind.
Achten Sie auf die Sichtbarkeit. Alle oben beschriebenen Typen und Methoden sollen überall verwendbar sein. Die Sichtbarkeit von Implementierungsdetails soll so stark wie möglich eingeschränkt werden. Sichtbare Implementierungsdetails beeinflussen die Ersetzbarkeit.
Schreiben Sie nicht mehr als eine Klasse in jede Datei (ausgenommen geschachtelte Klassen), halten Sie sich an übliche Namenskonventionen (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.