Karel J. Robot Simulator für vereinfachte Syntax

Klassen auf mehrere Dateien verteilen

Mehrere Dateien

In Java ist es möglich und auch durchaus elegant, verschiedene Klassen auf verschiedene Dateien zu verteilen. Dabei müssen gewisse Konventionen eingehalten werden, damit der Compiler diese Klassen auch findet (etwas vereinfacht):
Eine Klasse mit dem Namen classname muß in der Datei classname.java stehen. Groß-/Kleinschreibung ist dabei relevant!
Es dürfen zwar mehrere Klassen in einer Datei stehen (aber nur eine, die public ist), dann findet der Compiler diese Klassen aber unter gewissen Umständen nicht.
Man kann dem Compiler anzeigen, daß eine Klasse aus einer anderen Datei verwendet wird, indem man import classname; an den Anfang der Datei schreibt. Das muß aber erstmal nicht sein. Das import hat in erster Linie etwas zu tun mit packages, worauf ich aber nicht eingehen werde.
Aber Achtung! Wenn Ihr das so macht wie eben beschrieben, müssen die Klassen, die in den .java Dateien stehen, in echtem Java code geschrieben sein. Das bedeutet: kein loop, das package kareltherobot wird nicht richtig importiert und er Konstruktor <init>(int, int, int, int) wird nicht automatisch eingefügt!
Daher noch eine andere Möglichkeit: Verteilt die Klassen auf mehrere Task-Dateien. Dann müssen diese aber in der richtigen Reihenfolge nacheinander compiliert (im Simulator ausgeführt) werden. Das ist also nicht möglich, wenn die Klassen sich gegenseitig verwenden. Denkt auch daran, daß immer ein Task vorhanden sein muß!
Wenn Ihr das so macht, beachtet noch folgendes: Wenn der Compiler eine .class Datei findet, dann benutzt er die Klasse, die sich darin befindet und nicht die evtl. geänderte Version in Eurer Task-Datei. Also, um sicherzustellen, daß alles funktioniert, müßt Ihr alle .class Dateien löschen und alles nochmal neu erstellen. Schreibt Euren Tutoren gegebenenfalls auch in welcher Reihenfolge die Dateien auszuführen sind!

Konstruktoren und nicht-Roboter Klassen

Mit den Konstruktoren hat es einige Verwirrung gegeben, insbesondere dadurch, daß sich das Verhalten des Simulators geändert hat. Ich beginne mal damit, das Verhalten von echtem Java zu beschreiben:
Wird in einer Klasse gar kein Konstruktor definiert, fügt der Javacompiler einen Konstruktor ohne Argumente (noArgs-Konstruktor) ein, der gar nichts macht.
Wird mindestens ein Konstruktor definiert, so wird kein noArgs-Konstruktor angelegt. Wenn man ihn haben will, muß er explizit angelegt werden.
Innerhalb eines Konstruktors kann der Konstruktor der (direkten) Superklasse mit dem Befehl super( /*Paramter ...*/ );. Dieser Befehl muß der erste Befehl des Konstruktors sein.
Steht dort kein solcher Befehl, so fügt der Compiler sozusagen den Befehl super(); ein. D.h. es wird der noArgs-Konstruktor der direkten Superklasse ausgeführt.
Wenn diese Superklasse jetzt gar keinen noArgs-Konstruktor besitzt, führt das zu einem Fehler. Es muß also explizit ein anderer Konstruktor ser Superklasse ausgeführt werden!
Konstruktoren werden nicht vererbt. Wenn also die Ahnenklasse einen Konstruktor Ahne( int a ) hat, den die Erbenklasse auch haben soll, muß er explizit angegeben werden:

Erbe( int a )
{
	super( a );
}

Und nun zu dem Verhalten des Simulators: Da Ihr Euch zu Anfang nicht mit soetwas herumschlagen solltet, kopiert der Simulator den "Roboter-Standardkonstruktor" selbst. Gemeint ist ur_Robot( int street, int avenue, int direction, int beepers ). Das hat bei einigen schon zu dem Problem geführt, daß sie diesen Konstruktor auch selbst angegeben hatten, und er deshalb nach der Bearbeitung durch den Simulator zweifach definiert war. Wenn Ihr also eigene Konstruktoren angeben wollt, müssen diese nur eine andere Signatur haben als vier ints.
Es ist im Moment nicht möglich, diesen Konstruktor nur in Roboter-Klassen einzufügen, weshalb er in jede Klasse, die in einer Task-Datei steht, eingefügt wird. Dann kann es natürlich passieren, daß die Superklasse gar keinen Konstruktor mit vier ints hat, und deshalb dieser super-Aufruf nicht compiliert werden kann. Das ist vom Konzept her auch kein Fehler, weil in der Task-Datei nur Roboter-Klassen stehen sollen. Ich kann Euch aber zwei Workarounds anbieten:
erstens: schreibt solche Klassen in externe Dateien. Dazu bitte den oberen Text beachten.
zweitens: das ist zwar nicht elegant, aber man kann auch einfach nicht-Roboter-Klassen von ur_Robot ableiten. Dann gibt es keinen Compilerfehler und der ur_Robot code muß ja nicht benutzt werden (soetwas wie turnLeft() etc.).
Wenn Ihr Roboter-Klassen in einer externen Datei definiert, wird nicht automaisch der Roboter-Standard-Konstruktor eingefügt. Das müßt Ihr dann selbst machen.