Übungsblatt 09a Design by Contract |
PI-1 2008/09 |
Assignment #1: Interface Inheritance, Implementation Inheritance (UE/PR) 20 Punkte
In einem mittelalterlichen Königreich soll das Finanz- und Steuerwesen auf EDV umgestellt werden. Die verschiedenen Bevölkerungsgruppen werden durch die folgende Klassenhierarchie modelliert:
Das Attribut
einkommen
gibt das tatsächliche Jahreseinkommen des Einwohners in Talern an,
die Methode
zuVersteuerndesEinkommen()
gibt das zu versteuernde Einkommen zurück und
die Methode
steuer()
gibt den Steuerbetrag für ein Jahr zurück.
Die Methode toString() soll eine folgender Maßen formatierte Ausgabe erzeugen z.b. für Adligen mit Einkommen von 100 Talern:
Adel
zu versteuerndes Einkommen: 100
Steuer: 20
Hinweis: this.getClass().getSimpleName() liefert den einfachen Namen einer Klasse als String zurück, also wenn Adel = new Adel(); dann ergibt a.getClass().getSimpleName() "Adel".
Diese Methoden sollen die für jeden Einwohner des Königreiches korrekte Werte gemäß der folgenden königlichen Vorschriften liefern:
Sofern dieses Gesetz nichts Gegenteiliges aussagt, hat jeder Einwohner sein gesamtes Jahreseinkommen zu versteuern.
Jeder Einwohner hat 10% seines zu versteuernden Einkommens als Steuer zu entrichten. Der Steuerbetrag wird auf ganze Taler abgerundet, jedoch beträgt die Steuer immer mindestens 1 Taler.
Der König zahlt auch für sein steuerpflichtiges Einkommen keine Steuern.
Für Angehörige des Adels beträgt die Steuer mindestens 20 Taler.
Bei Leibeigenen sind 12 Taler des Jahreseinkommens steuerfrei.
Implementieren Sie die Klassenhierarchie! Überlegen Sie sich zunächst, wie die
Methoden in der Klasse Einwohner implementiert werden müssen. Welche Methoden
müssen in den Unterklassen überschrieben werden?
Zusätzlich soll ein JUnit-Test geschrieben werden, die von jeder
nicht-abstrakten Klasse ein Objekt erzeugt, mit einem fiktiven Jahreseinkommen
von 100 Talern versieht und das zu versteuernde Einkommen und den Steuerbetrag
wieder ausgibt. Da die Methode
toString()definiert
ist, kann die Ausgabe effektiv als System.out.println(a) geschrieben werden!
Hinweise: Alle Einwohner sind entweder König(in), von Adel, Bauern oder
Leibeigene. Gemeinsame Attribute und/oder Methoden sollten in (gemeinsamen)
Basisklassen implementiert, Spezialisierungen in den abgeleiteten Klassen
durchgeführt werden.
Abgabe bei Goya.
Geben Sie folgende Dateien als Tar-Archiv steuer.tar
ab:
Einwohner.java, Adel.java, Koenig.java, Bauer.java, Leibeigener.java, Mytest.java
UNIX-Befehl zum einpacken:
tar -cvf steuer.tar Einwohner.java Adel.java Koenig.java Bauer.java
Leibeigener.java Mytest.java
Assignment #2: Polymorphism (UE)
Vollziehen Sie nach, was in folgendem Java-Code passiert und erläutern Sie die Ausgabe.
class
Base {
protected String s = "base";
protected String t = "base2";public String s() { return s; }
public String t() { return t; }
}class
Derived extends Base {
protected String s = "derived";
protected String t = "derived2";public Derived() { }
public String s() { return s; }
}public
class PolyTest {static void out(Object o) {
System.out.println(o); }public static void main(String[] args) {
Derived d = new Derived();
out( d.s );
Base b = d;
out( b.s );
out( d.s() );
out( b.s() );
out( d.t() );
out( b.t() );
}
}
Assignment #3: Using Interfaces (UE)
Definieren Sie eine Klasse InverseComparator, mit deren Hilfe im folgenden
Programm die
Argumente in umgekehrter lexikographischer Reihenfolge ausgegeben werden:
public
class InterfaceDemo {public static void main(String args[]) {
java.util.Arrays.sort(args, new InverseComparator());
for (int i = 0; i < args.length; i++)
System.out.println(args[i]);}
}
Assignment #4: Exceptions (UE)
Welche Ausgabe erzeugt das oben abgebildete Programm, wenn es wie folgt aufgerufen wird?
% java Test1 divide test null foo
Begründen Sie Ihre Aussage!
class
TestException extends Exception {
TestException() { super(); }
TestException(String s) { super(s); }
}public
class Test1 {public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
try {
thrower(args[i]);
System.out.println("Test: " + args[i] + " wirft keine Exception");} catch (TestException te) {
System.out.println("TestException vom Nutzer geworfen");} catch (Exception e) {
System.out.println("Test: " + args[i] + " wirft eine Standardexception: " + e.getClass().getName());
}
}
}static int thrower(String s) throws TestException {
try {
if (s.equals("divide")) {
int i = 0;
return i / i;
}
if (s.equals("null")) {
s = null;
return s.length();
}
if (s.equals("test")) {
throw new TestException("Test Nachricht");
}
return 0;
} finally {
System.out.println("[thrower(" + s + ") gerufen]");
}
}}