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!