OOP Vererbung im Computerspiel

Wayne139

Aktives Mitglied
Hallo ich habe folgende Probleme.
Es soll ein Computerspiel mit Superman programmiert werden.

Problem 1:
Aufgabe: privates Attribut-> personalMission vom Typ Mission:
ist eine Referenz auf die Mission, die der Superman zu erfüllen hat.

Wäre das so richtig? Ich habe auch eine Klasse Mission, aber dort ist nicht vorgegeben, dass ich personalMission habe.
Hat wahrscheinlich was mit der "Referenz" zu tun. Superheroes ist ein Klassenattribut, hab ich das im Code richtig gemacht?
Java:
private Mission personalMission;
pirvate static int superheroes=0;

public Superman(Mission personalMission){
    this.personalMission=personalMission;
  }

Problem2:
Die Implementierung der Methode vergessen() der Schnittstelle vergesslich erniedrigt beim
Aufruf das Wissen (Knowledge) des Superhelden um 1.
Die Schnittstelle vergesslich enthält als einzige Methode die Methode vergessen(),
welche keinen Rückgabewert liefert.

Eine Schnittstelle ist wahrscheinlich ein Interface
Mein Code:
Java:
  public void vergessen(){
    knowledge--;
  }
 
  public interface vergesslich{
    
    public void vergessen();
  }

Problem3:
Die Methode adjustMissionTime (int zeit) subtrahiert die zeit von der verbleibenden
missionTime. Die Methode ist Teil von der Klasse "Mission"

Java:
  public int adjustMissionTime(int zeit){
    return (int) missionTime = (int) missionTime-zeit;
  }
Hier bekomme ich nicht richtig hin, die missionTime(double)-zeit(int) zu rechnen.
Ich glaub das lässt sich mit einem cast lösen?
 
Zu Problem 1: ja, richtig. "Referenz" bedeutet ja nur mal "Verweis". Das Attribut personalMission verweist also auf eine Instanz (Objekt) der Klasse Mission. Intern sieht das so aus, dass personalMission einfach die Adresse des Mission-Objekts speichert, an der dieses im Speicher zu finden ist. Das ist zwar hier unerheblich, aber diese Info erleichtert das Verständnis an einigen Stellen m.E. enorm.

Zu Problem 2: ist das "vergesslich" wirklich klein geschrieben? Das ist ja ekelhaft (in Java schreibt man Namen von Typen - und dazu gehören auch Interfaces - per Konvention in UpperCamelCase). Das aber nur nebenbei. Ansonsten: auch richtig - Schnittstelle ist interface. Das public vor void vergessen() kannst Du Dir sparen, da alle Methoden in einem interface automatisch public sind.

Außerdem muss Deine Klasse die Schnittstelle auch implementieren (implements).

Zu Problem 3: mach das mal in zwei Zeilen und vergiss den Cast - das macht Java automatisch. Fehler gibt es nur in die umgekehrte Richtung (Zuweisung eines double-Werts an eine int-Variable), weil hier Informationen verloren gehen können.
 
Danke für die Antwort mihe7

Hier ist noch die komplette Aufgabenstellung.
Ich habe die Stellen wo ich Probleme habe schwarz markiert.
----------------------------------------------------------------------------------------------------------------------------------------
Aufgabe

Sie wollen für ein Computerspiel die Actionfigur erstellen. Die Klasse Superman hat folgende privaten Attribute:
realName vom Typ String:
Der Name des Actionhelden im normalen Leben.

knowledge vom Typ int:
Eine Zahl zwischen 1 und 10 (jeweils inklusive), welche sein Wissen angibt (1 ist gering, 10 ist optimal).

superheroes vom Typ int:
Ist ein Klassenattribut und gibt an, wie viele Supermänner zurzeit unterwegs sind. Der Anfangswert ist 0. Er erhöht sich entsprechend bei der Erzeugung neuer Supermänner.

personalMission vom Typ Mission:
ist eine Referenz auf die Mission, die der Superman zu erfüllen hat.

personalTime vom Typ double:
Gibt an, wie viel Zeit der Superman insgesamt für die Mission zur Verfügung hat.

Superman implementiert weiterhin die Schnittstelle vergesslich (Definition der Schnittstelle im Anschluss weiter unten).

Die Klasse verfügt über einen allgemeinen Konstruktor, der alle Attribute initialisiert (außer dem Klassenattribut) und die Anzahl der superheroes um 1 erhöht.

Die öffentliche Methode kaempfen(int zeit) hat keinen Rückgabewert. Der Superman kämpft die angegebene Zeit in Minuten für die PersonalMission. Die Zeit, die er kämpft, wird von der PersonalTime abgezogen. Ist die zeit größer als PersonalTime, so wird eine Meldung ausgegeben „Die Zeit ist abgelaufen“.
Der Erfolg von kaempfen() hängt von dem Wissen (knowledge) des Superman ab, d.h. stimmen knowledge und difficulty überein, verkürzt sich die MissionTime um genau den Betrag zeit. Ist difficulty doppelt so groß wie knowledge, braucht er doppelt soviel zeit. Umgekehrt gilt auch, dass er die halbe zeit braucht, wenn sein knowledge doppelt so groß ist, wie die difficulty, usw.


Die Methode ueben() hat ebenfalls keinen Rückgabewert und erhöht beim Aufruf das Wissen (knowledge) des Superhelden um 1.

Die Methode toString() liefert eine Zeichenkette mit Namen, Wissensstand, Anzahl der Superhelden und Zeit, die der Superheld noch zur Verfügung hat.

Die Implementierung der Methode vergessen() der Schnittstelle vergesslich erniedrigt beim Aufruf das Wissen (Knowledge) des Superhelden um 1.

Die Schnittstelle vergesslich enthält als einzige Methode die Methode vergessen(), welche keinen Rückgabewert liefert.


Weiterhin gibt es eine Klasse Mission, welche die Aufgabe beschreibt, die der Superman erfüllen soll. Sie hat die folgenden privaten Attribute:
missionTime vom Typ double:
Gibt an, in welcher Zeit die Aufgabe gelöst werden muss.

difficulty vom Typ int:
Gibt an, wie schwierig die Mission ist.

Die Klasse verfügt über einen allgemeinen Konstruktor, der alle Attribute initialisiert.

Die Methode adjustMissionTime (int zeit) subtrahiert die zeit von der verbleibenden missionTime.

Weiterhin existiert eine öffentliche Methode zum Zugriff auf das Attribut difficulty.
-------------------------------------------------------------------------------------------------------------------------------------------


Mein Code sieht momentan so aus.
Die Klasse Superman
Java:
public class Superman implements Vergesslich{
  private String realName;
  private int knowledge;
  private static int superheroes=0;
  private Mission personalMission;
  private double personalTime;
  
  public Superman(String realName, int knowledge, Mission personalMission, double personalTime){
    this.realName=realName;
    this.knowledge=knowledge;
    this.personalMission=personalMission;
    this.personalTime=personalTime;
    superheroes++;
  }
  
  public void kaempfen(int zeit){
    if(knowledge==getDifficulty()){
      missionTime-=zeit;
    }
    if(difficulty/knowledge>=2){
      missionTime-=2*zeit;
    }
    if(knowledge/difficulty>=2){
      missionTime-=zeit/2;
    }
    if(zeit>personalTime){
      System.out.println("Zeit ist abgelaufen");
    }
    else{
      personalTime-=zeit;
    }
    
  }
  
  public void ueben(){
    knowledge++;
  }
  
  public String toString(){
    return realName+""+knowledge+""+superheroes+""+personalTime;
  }
  
  public void vergessen(){
    knowledge--;
  }  
}
Mit der Methode kaempfen() habe ich noch Probleme. Könnte es sein, dass Superman noch von Mission erben muss?
Also Superman extends Mission?



Und die Klasse Mission
Java:
public class Mission{
  private double missionTime;
  private int difficulty;
  
  
  public Mission(double missionTime, int difficutly){
    this.missionTime=missionTime;
    this.difficulty=difficulty;
  }
  
  public double adjustMissionTime(int zeit){
    return missionTime-=zeit;
  }
  
  public int getDifficulty(){
    return difficulty;
  }
  
  public void setDifficulty(int d){
    difficulty=d;
  }
}

Zusätzlich habe ich noch eine weitere Klasse für die Methode Vergesslich gemacht
Klasse Vergesslich
Java:
  public interface Vergesslich{   
    public void vergessen();
  }
Dass ich Vergesslich abseits von der Klasse Superman geschrieben habe ist so richtig?
Ich hatte Vergesslich vorher in Superman drin (Es kamen Fehlermeldungen beim Compilieren).
 
Ich will jetzt noch eine Klasse SuperJavaMan hinzufügen, die von Superman erbt.
Meine Konstruktoren sehen so aus:
Java:
public class SuperJavaMan extends Superman{
 
  //Allgemeiner Konstruktor
  SuperJavaMan(String realName, int knowledge, Mission personalMission, double personalTime){
    super(realName, knowledge,personalMission,personalTime);
}

  //Standardkonstruktor
  SuperJavaMan(){
    super(realName, knowledge,personalMission,personalTime);
  }
}
Hier ist das Problem, dass die privaten Variablen aus Superman nicht im Standardkonstruktor SuperJavaMan visible sind. Wie kann man das lösen ohne in Superman die Variabeln public zu machen?

Und ich habe noch eine Frage zum UML, ich sollte nur von Superman und Mission ein UML machen und ich möchte nur wissen ob das so passt, die Methode vergessen() müsste ja Abstrakt sein, aber Dia macht die Methode nicht kursiv. Ich benutze für die UML erstellung Dia, wenn mir jemand was anderes empfehlen kann, bitte schreiben.Vielen Dank für alles.
12743

12744
 
Hier ist das Problem, dass die privaten Variablen aus Superman nicht im Standardkonstruktor SuperJavaMan visible sind.
Nein, wenn überhaupt, dann ist das Problem, dass Superman keinen Standardkonstruktor hat. Die Variablen werden ja im Konstruktor gerade erst initialisiert.

Abgesehen davon: protected (im UML # statt -) sorgt dafür, dass auf Methoden und Attribute in abgeleiteten Klassen direkt zugegriffen werden kann - sollte man aber in der Regel nicht brauchen.

die Methode vergessen() müsste ja Abstrakt sein, aber Dia macht die Methode nicht kursiv
Die Methode vergessen() in Superman ist nicht abstrakt - dort gibt es eine konkrete Implementierung. Wäre die Methode in Superman abstrakt, dann wäre die ganze Klasse abstrakt.

Was Du machen solltest wäre folgendes: die Methode vergessen() aus Superman entfernen, ein neues Element mit dem Stereotyp «interface» und dem Namen Vergesslich (kursiv, weil abstrakt) einführen. Dann eine gestrichelte Linie von Superman zu Vergesslich mit Generalisierungspfeil in Richtung Vergesslich. Alternativ: Lolipop. Google einfach mal nach UML und Interface in der Bildsuche, dann siehst Du gleich, was damit gemeint ist 🙂
 

Zurück
Oben