Vorgegeben waren 2 Situationen, in denen Down-Casts zulässig sind, wobei aber Laufzeittests erforderlich sind. Für jede dieser Situationen sollte ein Beispiel konstruiert werden, das übersetzbar ist, aber zur Laufzeit eine Laufzeitausnahme wegen unkorrekter Typisierung des Casts erzeugt.
In einem zweiten Schritt sollten die Beispiele, unter Beibehaltung derselben Down-Casts so abgewandelt werden, daß keine Laufzeitausnahme mehr auftritt.
Zu jedem dieser Beipiele sollte eine kurze Erläuterung des erzielten Effektes verfaßt werden.
Vorgegebene zulässige Down-Cast Situationen:
Beispiel zu (a):
Mit ClassCastException:
//DowncastA_Exception interface K {} // ein Interface K class T {} // eine beliebige Klasse T class S implements K {} // und eine Klasse S, die K implementiert class DowncastA_Exception { public static void main(String argv[]) { K interf_obj = new S(); // packe Objekt vom Typ S in Variable interf_obj T class_obj = (T) interf_obj; // versuche ein Objekt des Typs T aus der // Variable zu holen -> gibt Exception } }
DowncastA_Exception.java zum Mitnehmen
Ohne ClassCastException:
//DowncastA_NoException interface K {} // ein Interface K class T {} // eine beliebige Klasse T class S extends T implements K {} // und eine Unterklasse S von T, die K implementiert class DowncastA_NoException { public static void main(String argv[]) { K interf_obj = new S(); // packe Objekt vom Typ T in Variable T class_obj = (T) interf_obj; // versuche ein Objekt des Typs T aus der // Variable zu holen -> geht! } }
DowncastA_NoException.java zum Mitnehmen
Erläuterung zu (a): Der Cast von einem beliebigen Interface-Typ K zu einer beliebigen Klasse T, die nicht final ist, ist mit dem folgendem Hintergedanken erlaubt: es könnte ja sein, daß eine Variable vom Typ K eine Instanz einer Unterklasse S von T enthält, die dann natürlich nach T gecastet werden kann. Eine solche Unterklasse S von T muß allerdings K implementieren, da sich sonst keine Instanz von ihr in einer Variable vom Interface-Typ K befinden könnte. Erst zur Laufzeit stellt sich heraus, ob dieser Hintergedanke zutrifft oder nicht.
Beispiel zu (b):
Mit ClassCastException:
//DowncastB_Exception interface K {} // 2 beliebige Interfaces K interface J {} // und J class S implements K {} // eine Klasse S, die eines dieser // Interfaces implementiert class DowncastB_Exception { public static void main(String argv[]) { K interf_obj_1 = new S(); // packe Objekt vom Typ S in Variable interf_obj_1 J interf_obj_2 = (J) interf_obj_1; // versuche ein Objekt des Typs J aus der // Variable zu holen -> gibt Exception } }
DowncastB_Exception.java zum Mitnehmen
Ohne ClassCastException:
//DowncastB_NoException interface K {} // 2 beliebige Interfaces K interface J {} // und J class S implements K,J {} // eine Klasse S, die beide // Interfaces implementiert class DowncastB_NoException { public static void main(String argv[]) { K interf_obj_1 = new S(); // packe Objekt vom Typ S in Variable interf_obj_1 J interf_obj_2 = (J) interf_obj_1; // versuche ein Objekt des Typs J aus der // Variable zu holen -> geht! } }
DowncastB_NoException.java zum Mitnehmen
Erläuterung zu (b): Klasse S implementiert im ersten Fall (nur) das Interface K. Daher kann ein Objekt vom Typ S in einer Variable vom Interface-Typ K gelagert werden. Der Cast von dieser Variable in eine vom Typ J schlägt allerdings fehl, da J von Objekten des Typs S nicht implementiert wird. Implementiert S aber neben K zusätzlich auch noch J, so ist der Cast möglich und es tritt kein Laufzeitfehler auf.
Der bekannte Algorihmus Sieb des Erathostenes ermittelt die Primzahlen in einem gegebenen Wertebereich. Es sollte ein Java-Applet entworfen und implementiert werden, das die Arbeitweise des Sieb des Erathostenes durch eine geeignete animierte Darstellung verdeutlicht (bei festgelegtem Wertebereich von 1 bis 100 für die Zahlen). Die Aninmation sollte durch Drücken eines "Go"-Knopfes gestartet werden. Da wir eine große Menge guter Animationen in den Abgaben hatten, präsentieren wir hier eine möglichst repräsentative Auswahl aus den abgegebenen Lösungen.
VORSICHT!
Viele der abgegebenen und hier gezeigten Lösungen sind allerdings keine brauchbaren
Applets, da sie die init(), repaint(), paint(), etc. Methoden, die im Leben
eines Applets wesentlich sind, nicht implementieren.
Dies erkennt man beispielsweise daran, daß solche Applets nach Verdecken und
Wiederaufdecken des Browsers durch andere Fenster recht kaputt aussehen!