Hilfe beim Bluej Programmieren?

1 Antwort

1) Innerhalb des Klassenkörpers sind zwar Deklarationen und Initialisierungen von Feldern erlaubt, jedoch keine weiteren Anweisungen, wie diese Definition:

laeuferfeld = new Laeufer[8];

Verbinde also diese Zeile mit der vorherigen Zeile zu einer Initialisierung. Es ist so eh kürzer.

Laeufer[] laeuferfeld = new Laeufer[8];

2) Hier

public void {

erstellst du eine Methode ohne Namen (und Argumentenliste), was nicht zulässig ist. Schau dir deine anderen Methoden an, dort hast du es doch schon richtig gemacht.

Des Weiteren würde ich an der Stelle einmal hinterfragen, wo diese Funktionalität benötigt wird.

3) Die Klasse Laeufer hast du hoffentlich irgendwo schon definiert? Wie sie aussehen muss, steht ja im obigen Diagramm.

4) In der Methode anDenStart weist du dem ersten Eintrag des Arrays einen Wert einer Variable laeufer1 zu. Das wäre an sich ok, wenn es die Variable denn überhaupt geben würde.

Wenn schon, müsste es so aussehen:

Laeufer laeufer1 = new Laeufer("Laeufer 1");
laeuferfeld[0] = laeufer1;

Allerdings denke ich, dass in der Methode alle Felder des Arrays gefüllt werden sollen. Nicht nur das Erste.

5) Dieser Code-Block:

{
  laeuferfeld[1].getName();
}

ergibt m.E. überhaupt keinen Sinn. Du solltest wissen, dass dieser ausgeführt wird, wenn ein Objekt der Klasse Wettlauf kreiert wird. Zu dem Zeitpunkt ist dein Array noch leer. Also gibt es auch kein Laeufer-Objekt bei Index 1, dessen Name aufgerufen werden kann. Stattdessen ist das Array noch mit null-Werten gefüllt.

Selbst wenn das Element existieren würde: Es wirft seinen Namen in den Raum und der wird nirgenwo verwendet.

Lösche diesen Block am besten komplett.

Schau soweit erst einmal, dass du beide Klassen so implementiert hast, wie es das Diagramm vorgibt. Beachte dabei das Prinzip der Kapselung. Felder werden mit einem Zugriffsmodifikator ausgestattet, der verhindert, dass sie von außen sichtbar / veränderbar sind. Den Zugriff handhaben stattdessen Methoden.

Dazu eine Erklärung (anhand eines Beispiels):

class Person {
  int age;
}

// main:
Scanner reader = new Scanner(System.in);

Person somePerson = new Person();
somePerson.age = reader.nextInt();
Person anotherPerson = new Person();
anotherPerson.age = reader.nextInt();

Stell dir vor, es käme zu diesem Code einmal die Anforderung hinzu, dass Personen im Alter nur zwischen einer bestimmten Zeitspanne liegen dürfen. Momentan kannst du dem Feld age ja fast jede Zahl zuordnen. Z.B. -5, 210, ...

Folgendermaßen müsste vor jeder Zuweisung sichergestellt werden, dass der zugewiesene Wert in der beschriebenen Grenze liegt.

Person somePerson = new Person();
int age = reader.nextInt();

if (age > 0 && age < 122) {
  somePerson.age = age;
}

Person anotherPerson = new Person();
age = reader.nextInt();

if (age > 0 && age < 122) {
  anotherPerson.age = age;
}

Das ist aufwendig und fehleranfällig (es könnte ja eine Prüfung irgendwo vergessen werden oder man macht irgendwo einen Tippfehler). Zudem könnte sich diese Altersgrenze in ferner Zukunft erneut ändern und müsste wieder bei jeder Zuweisung angepasst werden.

Kürzer geht es daher, indem man den direkten Zugriff auf age beschränkt und nur eine Schnittstelle definiert:

class Person {
  private int age; // field is private

  public void setAge(int age) {
    if (age > 0 && age < 122) {
      this.age = age;
    }
    else {
      System.err.println("Age is invalid!");
    }
  }
}
               
// main:
Scanner reader = new Scanner(System.in);

Person somePerson = new Person();
somePerson.age = reader.nextInt(); // error, not accessible anymore
somePerson.setAge(reader.nextInt()); // correct

Person anotherPerson = new Person();
anotherPerson.setAge(reader.nextInt());

Bei der getName-Methode für den Läufer hast du noch so eine Schnittstelle, nur dass diese in dem Fall einen Wert zurückgeben soll. In einfacher Form könnte sie so aussehen:

public String getName() {
  return this.name;
}

Aber so wie auch der Setter (für das Beispiel mit dem Alter) kann ein Getter als Filter dienen. Angenommen, für jeden Läufer, der Thomas heißt, sollte stattdessen die Kurzform Tom zurückgegeben werden.

public String getName() {
  if ("Thomas".equals(this.name)) {
    return "Tom";
  }

  return this.name;
}

Implementiere für jedes Feld deiner Klassen Schnittstellen zum Setzen und Einholen des Wertes.

Nachdem du die beiden Klassen fertiggestellt hast, warten noch die konkreten Implementationen der Methoden auf dich, die für die Wettlauf-Klasse definiert wurden. Sie sind bei dir ja noch leer.

Überlege zunächst, welche Funktion sie erfüllen sollen bzw. was in ihnen genau passieren soll. Beschreibe dies mit 1-2 Sätzen / Stichpunkten und beginne danach, diese benötigten Vorgang genauer, in einzelnen Schritten zu beschreiben. Du kannst dir dafür einen Programmablaufplan malen, ein Struktogramm, o.ä.. Eine Übersetzung in Java-Code kommt erst ganz am Schluss.

PS.: Noch ein Tipp bezüglich der Berechnung einer Zufallszahl zwischen zwei Grenzen (die untere Grenze ist inklusiv, die obere exklusiv):

int zufallszahl = (int) (Math.random() * (max - min)) + min;