OOP Klausur-Übung Öpnv

Diskutiere Klausur-Übung Öpnv im Java Basics - Anfänger-Themen Bereich.
T

theqwe

Hallo zusammen,

ich versuche mich gerade an einer alten Klausur Aufgabe. Die finde ich besonders schwierig, weil ich überhaupt nicht mehr weiter weiß. Die Aufgabe sieht so aus:

Java:
/*
Ergänzen Sie in den folgenden Klassen die notwendigen Schlüsselworte und notwendigen Methoden,
so dass die Ausgabe des Programms wie folgt aussieht:
Bahn S1 (id 1) kostet auf 100km 10 Euro
Bus A21 (id 2) kostet auf 1000km 50 Euro
Bahn R3 (id 3) kostet auf 11km 1,1 Euro
Bus B11 (id 4) kostet auf 12km 0,6 Euro

Hinweis: Sie dürfen keineweiteren Objekt-oder Klassenattribute hinzufügen.*/

public classTest {
    
    public static void main (String[] args) {
        ÖpnvI[] feld = { new Bahn("S1", 100), new Bus("A21", 1000), new Bahn("R3", 11),new Bus("B11", 12) };
        
        for(int i = 0; i < feld.length; i++) {
            System.out.println(feld[i]);
        }
}
    
public ______ ÖpnvI {
    double getPreisProKm();
}
public ______ class Öpnv ______ ÖpnvI {
    
    private static int n = 0;
    private int id;
    private String name;
    private int km;
    
    private double berechnePreis() {
        
        returnkm * getPreisProKm();
    }

public class Bus extends Öpnv {
}
    
public class Bahn extends Öpnv {
}

Mein Problem besteht darin, die Konstruktoren richtig zu nutzen. Außerdem weiß ich nicht, ob ich noch Methoden erstellen darf, die die privaten Variablen beschreiben dürfen, weil sie aus den Klassen Bus und Bahn ja nicht sichtbar sind. Die _____ Lücken müssen wir ergänzen. Mein Code sieht wie folgt aus:

Java:
public interface ÖpnvI {

    double getPreisProKm();
}

public abstract class Öpnv implements ÖpnvI {

    private static int n = 0;
    private int id;
    private String name;
    private int km;
    
    private double berechnePreis() {
        
        return km * getPreisProKm();
    }
    
    @Override
    public double getPreisProKm() {
        
        return 0;
    }
}

public class Bus extends Öpnv {

    public Bus() {
        
    }
    
    public Bus(String name, int km) {
        
    }
}

public class Bahn extends Öpnv {

    public Bahn() {
        
    }
    
    public Bahn(String name, int km) {
        
    }
}
Wenn man das Programm ausführt, sieht man schonmal die Speicheradresse der Instanzen. Wie mache ich jetzt weiter?

Danke im Voraus ;)
 
J

JustNobody

Also erst einmal: Nach meinem Verständnis ist die Öpnv Klasse ja abstrakt, weil sie eben keine Implementation von getPreisProKm hat. Die macht da so zumindest keinen Sinn.

Die müsstest Du dann aber in Bus und Bahn implementieren.

Damit Du eine vernünftige Ausgabe bekommst, müsstest Du die Methode toString() überschreiben.

Dann kannst Du Dir überlegen:
Was für Konstruktoren brauchst Du? Brauchst Du jeweils beide?
- wo könntest Du wie die id generieren?
- Wo und wie speicherst Du die anderen Werte (name und km)?
 
T

theqwe

Danke für deine schnelle Antwort.

Zur abstrakten Öpnv Klasse. In der Aufgabenstellung ist die Zeile dort durch etwas zu ersetzen. Ich habe da selber abstract eingetragen. Da es wohl keinen Sinn macht, scheint es ein Fehler zu sein 😅

Die Methode toString habe ich bei beiden schon benutzt. Problem ist, dass ich ja nicht auf die privaten Variablen der Superklasse zugreifen kann.
Den Standardkonstruktor brauche ich meiner Meinung nach nicht. Von den beiden Klassen wird ja eine Instanz erzeugt, die 2 Parameter ("Linie", Kilometer) übergeben. Also brauche ich nur meinen?!
Die ID könnte ich in der toString Methode vielleicht erhöhen lassen (id++)?

Ich stehe wie man sieht echt auf dem Schlauch.
 
F

fhoffmann

Dass die Klasse Öpnv abstrakt ist, ist schon korrekt.
Die Methode getPreisProKm() kannst du ja erst in den Klassen Bus und Bahn sinnvol implementieren.

Du musst beachten, dass die Member name, km und id in Öpnv private sind! Du kannst sie also nur (im Konstruktor) dieser Klasse setzen.
In den erbenden Klassen kannst du dann den Konstruktor der Oberklasse mit super aufrufen.
Ähnlich verhält es sich mit der toString-Methode.
 
T

theqwe

Alles klar. Das hat mir alles schon sehr weiter geholfen. Ich weiß nicht, ob es in der Aufgabe erlaubt ist, aber ich habe für die toString Methode Getter genutzt. Jetzt habe ich die Ausgabe fast so, wie gewünscht. Fehlt nur noch die Berechnung. Wo soll ich da ansetzen? Und ist die Umsetzung von mir sinnvoll und auch erlaubt?

Java:
public abstract class Öpnv implements ÖpnvI {

    private static int n = 0;
    private int id;
    private String name;
    private int km;
 
    public Öpnv(String name, int km) {
     
        this.name = name;
        this.km = km;
        this.id = ++n;
    }
 
    public String getName() {
     
        return name;
    }
 
    public int getID() {
     
        return id;
    }
 
    public int getKm() {
     
        return km;
    }

    private double berechnePreis() {
     
        return km * getPreisProKm();
    }
 
    @Override
    public double getPreisProKm() {
     
        return 0;
    }
}

public class Bus extends Öpnv {
 
    public Bus(String name, int km) {
     
        super(name, km);
    }
 
    public String toString() {
     
        return "Bus " + super.getName() + " (id " + super.getID() + ") kostet auf " + super.getKm() + "km " + getPreisProKm();
    }

    @Override
    public double getPreisProKm() {
      
        return 0.05 * super.getKm();  
    }
}

public class Bahn extends Öpnv {
 
    public Bahn(String name, int km) {
     
        super(name, km);
    }
 
    public String toString() {
     
        return "Bahn " + super.getName() + " (id " + super.getID() + ") kostet auf " + super.getKm() + "km " + getPreisProKm();
    }

    @Override
    public double getPreisProKm() {
      
        return 0.1 * super.getKm();
    }
}
EDIT: Die Berechnung habe ich auch hin bekommen. Das Problem ist nur, dass die Kommazahlen zu lang sind.
Bahn S1 (id 1) kostet auf 100km 10.0
Bus A21 (id 2) kostet auf 1000km 50.0
Bahn R3 (id 3) kostet auf 11km 1.1
Bus B11 (id 4) kostet auf 12km 0.6000000000000001
 
Zuletzt bearbeitet:
J

JustNobody

Das solltest du noch einmal prüfen. Der Preis pro km ist abhängig von den km die man fährt?

Dann musst du die Getter nicht mit super aufrufen. Die Methoden wurden ja geerbt und sind daher auch in Bus und Bahn vorhanden

Und die Ausgabe soll ja den ganzen Preis und nicht den Preis pro km anzeigen! (Hängt etwas mit dem ersten Punkt zusammen).

Und Öpvn sollte keine Implementation von getPreisProKm haben...
 
T

theqwe

Dann musst du die Getter nicht mit super aufrufen. Die Methoden wurden ja geerbt und sind daher auch in Bus und Bahn vorhanden
Danke, da war ich zu vorsichtig.

Und Öpvn sollte keine Implementation von getPreisProKm haben...
Auch entfernt. Hat eclipse automatisch hinzugefügt.
Das solltest du noch einmal prüfen. Der Preis pro km ist abhängig von den km die man fährt?
...
Und die Ausgabe soll ja den ganzen Preis und nicht den Preis pro km anzeigen! (Hängt etwas mit dem ersten Punkt zusammen).
Das verstehe ich nicht ganz. Man soll doch die gefahrenen Kilometer * den Kilometerpreis angeben oder?
 
F

fhoffmann

Du musst unterscheiden zwischen berechnePreis und getPreisProKm!

Das Problem mit den Nachkommastellen kannst du lösen mit:
Java:
String.format("%5.2f", berechnePreis())
 
T

theqwe

Ich habe beide Klassen jetzt folgendermaßen korrigiert:
Java:
@Override
    public double getPreisProKm() {
       
        return 0.05;
    }

    private double berechnePreis() {

        return getPreisProKm() * getKm();

    }
 
J

JustNobody

Das getPreisProKm sieht so gut aus.

Falls die berechnePreis Methode jetzt auch in Bus/Bahn ist: Das berechnePreis hast Du ja schon in Övpn - daher muss in Bus / Bahn keine solche Methode mehr.
 
T

theqwe

Falls die berechnePreis Methode jetzt auch in Bus/Bahn ist: Das berechnePreis hast Du ja schon in Övpn - daher muss in Bus / Bahn keine solche Methode mehr.
Ich habe die Methode in beiden drin. berechnePreis ist in der Superklasse doch auch private. Wie soll ich darauf dann zugreifen?
 
H

httpdigest

Ich würde sagen, du brauchst auf die Methode berechnePreis() doch überhaupt gar nicht von den Subklassen aus zugreifen. Diese Methode braucht nur von der abstrakten Oberklasse benutzt zu werden, und zwar, von deren toString() Methode.
 
J

JustNobody

Ok, das habe ich übersehen. Du hast in dem Punkt dann Recht.
 
H

httpdigest

Ok, das habe ich übersehen.
Ich würde sagen, dass du das nicht übersehen hast (wenn dein Post überhaupt eine Antwort auf meinen war). Du hast ja eigentlich dasselbe auch schon gesagt:
Das berechnePreis hast Du ja schon in Övpn - daher muss in Bus / Bahn keine solche Methode mehr.
Ich wollte nur etwas klarer hervorheben, wo denn berechnePreis() eigentlich nur genutzt werden braucht.
 
J

JustNobody

Meine Antwort hatte sich mit Deiner überschritten. Ich habe tatsächlich übersehen, dass die Methode private ist.

Wenn man also den Preis haben möchte, dann wäre so eine Methode notwendig. Aber du hast Recht, dass so eine Methode nicht für die Erledigung der Aufgabe benötigt wird. Das hatte ich aber bei meiner Antwort auf dem Smartphone so alles nicht ganz überblicken und ausführen können. Daher was es super, dass du auch schon geantwortet hattest :)

Die Erstellung in den abgeleiteten Klassen ist aber natürlich relativer Unsinn, da man offensichtlicher keinen doppelten Code haben kann...
 
T

theqwe

Also wäre die Aufgabe jetzt so beendet? Oder muss ich noch mit der Methode berechnePreis() aus der Oberklasse Öpnv was machen? Ich habe weiterhin die Methode in den erbendet Klassen drin.
 
H

httpdigest

muss ich noch mit der Methode berechnePreis() aus der Oberklasse Öpnv was machen?
Ja natürlich musst du die Methode berechnePreis() in der Oberklassen in der Öpnv.toString() (die EINZIGE toString() Methode übrigens in all deinen Klassen hoffentlich) benutzen. Du brauchst und sollst toString() sicherlich nicht in den Unterklassen implementieren. Und genauso wenig solltest du berechnePreis() in den Unterklassen definieren.
 
J

JustNobody

Das mag von der Funktion her ok sein (Es funktioniert hat), aber es ist nicht ideal. Je nach Anforderungen, die gelten, kann der mehrfache Code als Fehler gewertet werden.

Die Methode berechnePreis darf nur in Öpnv sein. Die abgeleiteten Klassen benötigen die Methode nicht. Da diese private sind, hast Du die nicht in der toString() Methode der jeweiligen Unterklassen zur Verfügung und Du musst schauen, wie Du dies gelöst bekommst. Eine Möglichkeit ist, wie von @httpdigest geschrieben: Du hast nur noch keine toString Methode in Öpnv. Man das ist nicht zwingend. Man könnte sich auch überlegen, wie man die Ausgabe zusammen setzen kann und dann hätte man toString Methoden in allen Klassen.
 
Thema: 

Klausur-Übung Öpnv

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben