Könnt ihr mir bei dieser Javaaufgabe helfen?

1 Antwort

Also mein erster Tipp beim Drüberschauen: Entferne überflüssige Leerzeilen und rücke Code immer richtig ein. Das macht den Code viel besser lesbar.

Folgend gehe ich einmal die Klassen durch, beginnend bei der Rennschnecke.

1) Ich vermute mal, du kennst access modifier und das Prinzip der Kapselung noch nicht.

Um den Zugriff nach außen zu regeln, gibt es in Java vier verschiedene access modifiers: public, protected, package-private, private:

class SomeClass {
  public String[] wordsForEveryone; // public
  String[] wordsKnownInPackage; // package-private
  protected String[] wordsForChilds; // protected
  private String[] wordsOnlyForMe; // private
}

Welche Ebenen sie regulieren, kannst du hier nachlesen.

Bei dem Prinzip der Kapselung geht es nun darum, festzulegen, welche Informationen eines Objekts für andere Objekte von außen sichtbar / zugreifbar sein sollen. Zur Erklärung nutze ich gern das Beispiel der Mikrowelle: All die Technik und Funktionalität versteckt sie in ihrem Gehäuse, der Nutzer könnte eh nichts mit den Kabeln, etc. anfangen. Stattdessen präsentiert sie ihm nur ein Interface - Tasten, Knöpfe, um das Gerät zu bedienen. Diesem Prinzip solltest nach Möglichkeit stets folgen, um Beziehungen zwischen Objekten strikt zu trennen und dein Projekt übersichtlich zu halten (nur die Information nach außen preisgeben, die außen nötig ist). Du kannst alle Elemente einer Klasse (Attribute, Methoden, Konstruktoren, innere Klassen, Enums) mit den Modifikatoren belegen.

Wenn bei Attributen die Werte der Eigenschaften doch einmal von außen ansprechbar sein sollen, schreibe dir Methoden dafür (Getter und Setter genannt) und lasse die Attribute unsichtbar:

private String name;

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

public void setName(String name) {
  this.name = name;
}

Der Vorteil ist nun, dass du den Prozess - eine Zuweisung zu dem Namen bspw. abgekapselt hast. Du könntest da nun mit Leichtigkeit neuen Code in den Block zufügen, bspw. verhindern, dass eine Schnecke einmal Alfons heißt:

public void setName(String name) {
  if (name.equals("Alfons")) {
    return;
  }

  this.name = name;
}

Hättest du zuvor mit sichtbaren Attributen gearbeitet, hättest du jede Code-Stelle in deinem Projekt ausfindig machen müssen, an der der Name gesetzt wird, und die if-Kontrollstruktur einbauen müssen. Das ist ziemlich schlecht wart- und testbar.

2) Nutze für zusammengesetzte Wörter im Bezeichner die kamelHoeckerSchreibweise: z.B. maxGeschwindigkeit. Es macht den Code besser lesbar.

3) Das Attribut weg soll doch eigentlich darstellen, wie viel an Strecke bereits zurückgelegt wurde. Wieso verwendest du dann keinen numerischen Typ dafür?

4) Den Aufruf von super kannst du dir an dieser Stelle sparen, die passiert eh implizit. Nur wenn der Konstruktor der Basisklasse noch Informationen über seinen Konstruktor erwarten würde, müsstest du diese explizit bedienen.

class Base {
  public Base(String someVeryImportantInformation) {
  }
}

class Sub extends Base {
  public Sub() {
    super("The answer is 42.");
  }
}

5) Die Methode kriechen soll dafür sorgen, dass die Schnecke effektiv weiterkommt. Bei dir wird nur eine neue Zahl angelegt/berechnet, diese dann auf der Konsole ausgegeben und danach wieder weggeschmissen. So wird sich eine Schnecke nie weiterbewegen.

Du sollst einen zufälligen Wert berechnen, der zwischen der maximalen Geschwindigkeit und 0 liegt. (Verwende zur Berechnung das Attribut für die maximale Geschwindigkeit, nicht irgendeinen festen Wert wie 4, sonst nimmst du dem Programm die Flexibilität).

int randomVelocity = (int) (Math.random() * (maximumVelocity - 0)) + 0;

Dieser kennzeichnet die aktuelle Geschwindigkeit. Danach kommt etwas Physik ins Spiel:

geschwindigkeit = weg / zeit |*zeit
zeit * geschwindigkeit = weg

Das Ergebnis addierst du auf das Attribut drauf, welches den bereits zurückgelegten Weg speichert.

6) Die toString-Methode ist so richtig, dennoch ein Tipp für übersichtlicheren Code: Verwende die format-Methode. In dieser wird erst ein Template angegeben, wie dein String aussehen soll. Dieses Template beinhaltet Platzhalter, an dem folgende Argumente eingesetzt werden.

Beispiel:

int hour = 2;
int minutes = 52;
String text = String.format("In %d hours and %d minutes, the next train is coming.", hour, minutes);
System.out.println(text);

Schau hier für weitere Informationen dazu.

Die Testschnecke:

Wozu diese Klasse eigentlich? In der Aufgabenstellung wird sie nicht erwähnt und einen Unterschied zur Rennschnecke implementierst du nicht, sodass eine Vererbung eigentlich auch nicht notwendig ist.

Benenne die Klasse doch in Main um und behalte in ihr nur die main-Methode. So wird deutlich, dass es sich um den Startpunkt im Projekt handelt.

public class Main {
  public static void main(String[] args) {
    // ...
  }
}

Die Klasse Rennen:

1) Du überschreibst im Konstruktor die einzelnen Parameter, nachdem die Attribute gesetzt wurden? Was ist der Sinn dahinter?

name = "Schneckenrennen";
teilnehmer = 3;
schnecken[0] = // ...

Nachdem der Konstruktor zur Programmzeit abgearbeitet wurde, fliegen die Parameter eh wieder aus dem Speicher. Und wenn du die Attribute eigentlich überschreiben wolltest, macht das ebenso keinen Sinn.

Das Anlegen der Teilnehmer würde außerhalb (bspw. in main) stattfinden:

int streckenlaenge = // ...
Rennschnecke[] rennschnecken = new Rennschnecke[3];
schnecken[0] = new Rennschnecke(// ...
schnecken[1] = new Rennschnecke(// ...
schnecken[2] = new Rennschnecke(// ...

Rennen schneckenRennen = new Rennen("Schneckenrennen", rennschnecken, streckenlaenge);

Der Parameter teilnehmer (besser wäre eh: teilnehmerAnzahl) ist nicht notwendig. Ein Array weiß selbst, wie lang es ist (length-Attribut).

2) Deine addRennschnecke ist falsch. Der Name (der ja von der Aufgabe vorgegeben wurde) ist schon nicht fantastisch, weil er eine Kombi aus Deutsch und Englisch darstellt.

Wenn eine neue Rennschnecke hinzugefügt werden soll, darfst du auch nur eine ergänzen, und die vorherigen Elemente des Arrays nicht wieder überschreiben. Außerdem arbeitest du wieder mit konstanten Werten. Angenommen, das Array an Schnecken würde nur zwei Schnecken beinhalten und du greifst in der Methode hart auf den Index 2 (das dritte, nun nicht existente Element) zu. Dann knallt es.

Überlege dir nun eher, wie du dein Array vergrößerst bzw. mehr Speicherplatz für neue Schnecken schaffst. Ja sicher, es gibt stattdessen auch die ArrayList oder Methoden, die es dir vereinfachen. Ich würde es an dieser Stelle aber nicht als richtige Lösung ansehen, denn es ist eine kleine Übung, die du zu diesem Zeitpunkt auf jeden Fall schon bewältigen können solltest. 😉

3) Das Entfernen einer Schnecke läuft daraufhin ähnlich ab. Erst läufst du durch jedes Element des Arrays, um die Schnecke mit passendem Namen zu finden. Dann schaust du, dass du dieses Element / diesen Index aus deinem Array entfernst. Das Array sollte danach keine leeren Plätze frei haben.

Wenn ich nun die weiteren fälligen Methoden anschaue, habe ich das Gefühl, du hast dich noch nicht mit Schleifen befasst? Wenn dem so sein sollte, sind die Aufgaben auch noch nicht lösbar für dich. Generell bist du mit dem Thema OOP dann schon zu weit vorgesprungen.

MittelEgo 
Fragesteller
 16.03.2019, 21:00

Danke erstmal für diese ausführliche Antwort!

Ich kenne die Modifier schon, doch der Begriff Kapselung ist mir noch nicht über dem Weg gelaufen. Zur Testschnecke: In der Aufgabe wurde angegben, dass ich mir ein Schneckenobjekt erzeugen soll, dass die Daten auf der Konsole ausgibt, doch ich habe es falsch verstanden und mir extra eine Klasse angelegt habe, um die Daten auszugeben. ^^ Ich habe ich mich auch mit Schleifen befasst, doch nur für kurze Zeit. Ich bin noch wirklich unsicher, wann und wo ich was einsetzen musst (Datentypen, Methoden, Parameter...). Ich habe außerdem mit hoher Wahrscheinlichkeit nicht alles im Kopf behalten, was ich gelernt habe. Aber nochmals danke, ich werde mir alle Grundlagen nochmal anschauen. :)

0
regex9  16.03.2019, 21:03
@MittelEgo

Ja, das wäre auch mein Rat. Übe sie alle, schrittweise, solange bis sie sitzen.

0