konzeptuelle Frage: In welcher Klasse definiert man am Besten Methoden, die die Kommunikation mit dem User regeln?

Diskutiere konzeptuelle Frage: In welcher Klasse definiert man am Besten Methoden, die die Kommunikation mit dem User regeln? im Java Basics - Anfänger-Themen Bereich.
M

MarkusFromBerne

Ich habe ein Programm, in dem es um verschiedene Klassen von Fahrzeugen geht. Die Fahrzeug-Klassen haben unterschiedliche Parameter und Methoden.

Der User soll entscheiden können, welche Methoden er benutzen will. Er kann bspw. neue Fahrzeuge generieren, diese auftanken, etc. Die Abfragen ("Wie heisst das neue Auto?" etc) laufen über Methoden.
Ich bin unschlüssig, in welcher Klasse ich diese Methoden definieren soll:
  1. in eine der Fahrzeug-spezifischen Klassen (Benziner, Fahrrad, etc.) macht mE kaum Sinn. Wenn das Programm bspw. fragen soll, was des Users nächster Schritt ist, hat das nur indirekt mit dem Objekten zu tun. Die Objekte bestimmen lediglich, welche Methoden "im Angebot" sind, also woraus der User überhaupt auswählen kann. (Gegenwärtig ist aber die range an Optionen von mir statisch festgelegt.)
  2. in ein interface macht mE gar keinen Sinn. Interfaces nutze ich, um Aspekte abzubilden, die nicht so richtig in übrige Klassenhierarchie passen. Wenn ich bspw. irgendwas mit C02-Ausstoss implementieren will, passt das zu Benziner, aber nicht zu Fahrrad. Da würd' ich also interfaces nutzen, um damit alle Benziner zu irgendwelchen CO2-Methoden zu zwingen.
  3. In der main-Klasse ist es zwar einigermassen sinnvoll, aber ich finde es "unästhetisch". Ich nutze die main am Liebsten nur, um alle meine anderen Sachen aufzurufen. So ein bisschen wie die Kommandozeile des terminals. Die soll auch einigermassen "rein" bleiben.
  4. Soll ich eine Klasse nur für solche Meta-Methoden machen? Mit Meta-Methoden meine ich Methoden, die selber nichts tun (keine Objekte instanziieren oder verändern), sondern nur den User fragen und dann die Methoden der passenden Klassen aufrufen.

Puh, je mehr ich schreibe, desto verworrener wird's....
Danke trotzdem

Java:
import java.util.*;

public class kapitel13a3 {
    public static void main(String[] args) {
        Auto a1  = new Auto("Audi", "quattro", 12500, 4, 150, 210, 60, 4, 5);
        LKW l1 = new LKW("Iveco", "longliner", 360000, 8, 300, 90, 250, 11, 30);
        a1.allInfosAboutTHISFahrzeug();
        l1.allInfosAboutTHISFahrzeug();
        askUserForNextOperation ();
        System.out.println("Ende des Programms");
    }

    public static void askUserForNextOperation () {
        Scanner askUserForNextOperation = new Scanner(System.in);
        int input=99;

        do {
            System.out.println("\nWillst du eine Funktion dieses Programms nutzen? Ja= 1, Nein=2");
            input = askUserForNextOperation.nextInt();
            if (input==1){
                proposeOptionstoUser();
            } if (input==2){
                System.out.println("Gut, dann geht's zum folgenden Programmschritt.");
            }
        } while ((checkUserInput(2, input))==false);
    }

    public static void proposeOptionstoUser () {
        Scanner proposeOptionstoUser = new Scanner (System.in);
        int input=99;
        do {
            System.out.println
            ("\nWillst du\n1: tanken\n2: fahren\n3: ein neues Fahrzeug generieren?");
            input = proposeOptionstoUser.nextInt();
            System.out.println();
            if (input==1){
                System.out.println("Tanken wird gestartet");
                //tanken (); //geht nicht weil ich gerade in einer statischen Methode bin
            }
            if (input==2) {
                System.out.println("Fahren wird gestartet");
                //fahren (); //geht nicht weil ich gerade in einer statischen Methode bin

            }
            if (input==3) {
                System.out.println("Generieren wird gestartet");
                //fahrzeugGenerieren (); //geht nicht weil ich gerade in einer statischen Methode bin
            }
        }
        while ((checkUserInput(3, input))==false);
        askUserForNextOperation();
    }

    //Hier wird geprüft, ob die User-Eingabe mit den Anzahl Optionen übereinstimmt
    public static boolean checkUserInput (int numberOfOptions, int userChoice){
        boolean userInputPossible;
        if (userChoice< (numberOfOptions+1)) {
            if (userChoice>0){
                userInputPossible = true;
            } else {
                System.out.println("Der eingebene Wert ist ungueltig.");
                userInputPossible = false;
            }
        } else {
            System.out.println("Der eingebene Wert ist ungueltig.");
            userInputPossible = false;
        }
        return userInputPossible;
    }
}

abstract class Fahrzeug{
    String marke, modell;
    double preis;
    int anzahlRaeder;

    public void fahren () {}

    public void allInfosAboutTHISFahrzeug (){
        System.out.println(
        "\nDas Modell "+modell+
        " der Marke "+marke+
        //Hier soll die Methode aufgerufen werden, die den ClassType bestimmt.
        " ist ein "+this.getClass().getSimpleName()+
        ".\nEs kostet "+preis+" Franken und hat "+anzahlRaeder+" Raeder.");
    }

    public Fahrzeug(String marke, String modell, double preis, int anzahlRaeder) {
        this.marke = marke;
        this.modell = modell;
        this.preis = preis;
        this.anzahlRaeder = anzahlRaeder;
    }
}

abstract class Benziner extends Fahrzeug{
    int ps, maxGeschwindigkeit;
    double verbrauchPro100k, Reichweite, aktuellerTankstand, tankSize;
    final double preisProLiterBenzin = 1.55;

    public double berechneKostenfuersVolltanken (){
        if (aktuellerTankstand>tankSize){
            System.out.println("Es kann nicht mehr Benzin im Tank sein als dessen Fassungsvermoegen.\nNaja, ich ignoriere das mal.");
        }
        return (tankSize-aktuellerTankstand)*preisProLiterBenzin;
    }

    public Benziner(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k) {
        super(marke, modell, preis, anzahlRaeder);
        this.ps = ps;
        this.maxGeschwindigkeit = maxGeschwindigkeit;
        this.tankSize = tankSize;
        this.verbrauchPro100k = verbrauchPro100k;
        Reichweite = berechneReichweite();
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Dieses Fahrzeug hat eine maximale Geschwindigkeit von "+maxGeschwindigkeit+
        " kmh und eine Leistung von "+ps+" PS.\nSein Tank fasst "+tankSize+
        " Liter, damit kann es bei einem Verbrauch von "+verbrauchPro100k+
        " L/100km "+Reichweite+
        " km weit fahren."
        );
    }

    public double berechneReichweite (){
        return Math.rint(((tankSize/verbrauchPro100k)*100));
    }


}

class Auto extends Benziner {
    int maxPassagiere;

    public Auto(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k, int maxPassagiere) {
        super(marke, modell, preis, anzahlRaeder, ps, maxGeschwindigkeit, tankSize, verbrauchPro100k);
        this.maxPassagiere = maxPassagiere;
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Maximal "+maxPassagiere+" Passagiere passen in dieses Auto.");
    }
}

class LKW extends Benziner {
    int maxLadung;

    public LKW(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k, int maxLadung) {
        super(marke, modell, preis, anzahlRaeder, ps, maxGeschwindigkeit, tankSize, verbrauchPro100k);
        this.maxLadung = maxLadung;
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Dieser LKW kann "+maxLadung+" Tonnen laden.");
    }
}

class Fahrrad extends Fahrzeug {
    double kalorienverbrauchProKm, gewicht;
    int anzahlGaenge;

    public void essen () {}

    public Fahrrad(String marke, String modell, double preis, int anzahlRaeder, double kalorienverbrauchProKm,
            double gewicht, int anzahlGaenge) {
        super(marke, modell, preis, anzahlRaeder);
        this.kalorienverbrauchProKm = kalorienverbrauchProKm;
        this.gewicht = gewicht;
        this.anzahlGaenge = anzahlGaenge;
    }
}
 
M

MarkusFromBerne

Beispiele für besagte Methoden:
  • Zeile 13: public static void askUserForNextOperation
  • Zeile 28: public static void proposeOptionstoUser
  • Zeile 55: public static boolean checkUserInput
 
mrBrown

mrBrown

Soll ich eine Klasse nur für solche Meta-Methoden machen? Mit Meta-Methoden meine ich Methoden, die selber nichts tun (keine Objekte instanziieren oder verändern), sondern nur den User fragen und dann die Methoden der passenden Klassen aufrufen.
Diese „Meta-Methoden“ sind dein User-Interface, die gehören wie du richtig sagst getrennt vom Model der Anwendung :)

Eine eigene Klasse, oder auch mehrere, ist völlig korrekt dafür.

Als Anmerkung zu deinem Code: du solltest nur einen einzigen Scanner initialisieren, ansonsten gehen uU Eingaben verloren.
 
M

MarkusFromBerne

Diese „Meta-Methoden“ sind dein User-Interface, die gehören wie du richtig sagst getrennt vom Model der Anwendung :)

Eine eigene Klasse, oder auch mehrere, ist völlig korrekt dafür.

Als Anmerkung zu deinem Code: du solltest nur einen einzigen Scanner initialisieren, ansonsten gehen uU Eingaben verloren.
@mrBrown: Vielen Dank für deine Hilfe! Ich habe mein Programm entsprechend umgeschrieben. Ausser die Scanner; reicht es, wenn ich einen einzigen Scanner zu allererst mal initialisiere? Kann ich diesen Scanner dann in allen Klassen und Methoden nutzen? Oder gilt die Initialisierung des Scanners nur für eine Klasse oder gar nur für eine Methode? Letztendlich ist ein Scanner ja nichts anderes als eine Methode in einer Klasse, die ich importiert habe.
 
mrBrown

mrBrown

Nur ein Scanner, der mit System.in arbeitet, sollte für das gesamte Programm genutzt werden. Den kannst du dann überall nutzen – wobei man das idealerweise eng begrenzt.

Letztendlich ist ein Scanner ja nichts anderes als eine Methode in einer Klasse, die ich importiert habe.
Ne, Scanner ist eine Klasse, und davon erstellst du ein Objekt, auf dem du Methoden aufrufst :)
 
M

MarkusFromBerne

aargh, kennt ihr das, wenn nach jedem gelösten Problem gleich (mindestens) ein neues Problem auftaucht?

Wie weiter oben beschrieben, habe ich meine Userabfragen uä in der Klasse "Commands" zusammengefasst. Aber es gelingt mir nicht, von dort aus auf die Objekte der übrigen Klassen zuzugreifen. Stets erhalte ich die Fehlermeldung "Cannot find symbol" mit Bezug auf mein "fahrzeuArray".

Es folgt nun allerlei nebensächliches. Ich schreibe es hin, damit meine Überlegungen deutlicher werden. Mir geht's hier eher um die konzeptuelle Ebene und meine (mis-)conceptions. Der eigentliche Code ist gleich darunter.

Folgendes habe ich ohne Erfolg getestet:

  1. neues Objekt der Fahrzeug-Klasse initialisiert, das nicht in einem Array liegt (These: das Array ist das Problem). Resultat: selbe Fehlermeldung
  2. Klasse "Commands" ins gleiche File wie der Rest kopiert. Resultat: selbe Fehlermeldung, weniger Übersichtlichkeit
  3. den Pfad zum Objekt expliziter gemacht: Fahrzeug.fahrzeugArray. Resultat: die Klasse mitgeben ist zwar möglich, scheint aber für was anderes gedacht zu sein. Jedenfalls auch keine Lösung. Wär' auch unsinnig, da ja Java durch den Objektnamen etc. weiss, welche Klasse gemeint ist.

Meine Überlegungen dazu:
  1. die Klasse "Commands" ist nicht in die gleiche hierarchische Struktur wie die übrigen Klassen eingebunden (Fahrzeug->Benziner->Pkw etc.). Das sollte eigentlich kein Problem sein. Interfaces sind hier auch keine gute Lösung.
  2. Ich habe das Ganze in reduzierter Form woanders reproduziert. Die "Cannot find symbol" Meldung kam auch. Immerhin sah's dort aus, als würde ich weiterkommen, wenn ich den Methoden in "Commands" Objekte mitgebe. Ich möchte das lieber so lösen, dass zunächst die existierenden Objekte ausgegeben werden, der User dann eines davon auswählt und die Methoden mit dieser Auswahl gefüttert werden.

Code des Hauptprogramms:
Java:
import java.util.Scanner;

public class kapitel13a3 {
    public static void main(String[] args) {
        Fahrzeug [] fahrzeugArray = new Fahrzeug [100]; //Das Array ist halt mal fix auf 100 Elemente eingestellt. Klar wäre automatisch verlängern besser...
        Auto a1  = new Auto("Audi", "quattro", 12500, 4, 150, 210, 60, 4, 5);
        fahrzeugArray [0] = a1;
        LKW l1 = new LKW("Iveco", "longliner", 360000, 8, 300, 90, 250, 11, 30);
        fahrzeugArray [1] = l1;
        fahrzeugArray[0].allInfosAboutTHISFahrzeug();
        fahrzeugArray[1].allInfosAboutTHISFahrzeug();

        //Aufruf einer Instanz von Commands, damit die Methoden dort nicht-statisch sind.
        //Geht wohl nicht anders?
        Commands commandsNonStatic = new Commands();
        //Und jetzt der Aufruf der Methoden im Commands, um den User auswählen zu lassen
        commandsNonStatic.askUserForNextOperation ();

        System.out.println("Ende des Programms");
    }

}

class Fahrzeug{
    String marke, modell;
    double preis;
    int anzahlRaeder;

    public void fahren () {}

    public void allInfosAboutTHISFahrzeug (){
        System.out.println(
        "\nDas Modell "+modell+
        " der Marke "+marke+
        //Hier soll die Methode aufgerufen werden, die den ClassType bestimmt.
        " ist ein "+this.getClass().getSimpleName()+
        ".\nEs kostet "+preis+" Franken und hat "+anzahlRaeder+" Raeder.");
    }

    public Fahrzeug(String marke, String modell, double preis, int anzahlRaeder) {
        this.marke = marke;
        this.modell = modell;
        this.preis = preis;
        this.anzahlRaeder = anzahlRaeder;
    }

    @Override
    public String toString() {
        return "Fahrzeug [anzahlRaeder=" + anzahlRaeder + ", marke=" + marke + ", modell=" + modell + ", preis=" + preis
                + "]";
    }
}

abstract class Benziner extends Fahrzeug implements Carbon2OEmission{
    int ps, maxGeschwindigkeit;
    double verbrauchPro100k, Reichweite, aktuellerTankstand, tankSize;
    final double preisProLiterBenzin = 1.55;

    public double volltanken (){
        System.out.println("Momentan sind "+aktuellerTankstand+"Liter Benzin im Tank.\nDieser Tank kann"+tankSize+"Liter aufnehmen.\n");
        if (aktuellerTankstand>tankSize){
            System.out.println("Es kann nicht mehr Benzin im Tank sein als dessen Fassungsvermoegen.\nNaja, ich ignoriere das mal.");
        }
        return (tankSize-aktuellerTankstand)*preisProLiterBenzin;
    }

    public Benziner(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k) {
        super(marke, modell, preis, anzahlRaeder);
        this.ps = ps;
        this.maxGeschwindigkeit = maxGeschwindigkeit;
        this.tankSize = tankSize;
        this.verbrauchPro100k = verbrauchPro100k;
        Reichweite = berechneReichweite();
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Dieses Fahrzeug hat eine maximale Geschwindigkeit von "+maxGeschwindigkeit+
        " kmh und eine Leistung von "+ps+" PS.\nSein Tank fasst "+tankSize+
        " Liter, damit kann es bei einem Verbrauch von "+verbrauchPro100k+
        " L/100km "+Reichweite+
        " km weit fahren."
        );
    }

    public double berechneReichweite (){
        return Math.rint(((tankSize/verbrauchPro100k)*100));
    }


}

class Auto extends Benziner {
    int maxPassagiere;

    public Auto(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k, int maxPassagiere) {
        super(marke, modell, preis, anzahlRaeder, ps, maxGeschwindigkeit, tankSize, verbrauchPro100k);
        this.maxPassagiere = maxPassagiere;
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Maximal "+maxPassagiere+" Passagiere passen in dieses Auto.");
    }

    public String calculateAndEvaluateEmission (){
        double checkLimit = verbrauchPro100k/maxPassagiere ; //Vorarbeit um zu prüfen, ob dieses Auto die Grenzwerte einhält
        String result; //Variable für das Resultat der Evaluierung
        if (checkLimit<limitByLaw){
            result = "Dieses Auto stosst bei maximaler Passagierzahl ("+maxPassagiere+") "+checkLimit+"Gramm CO2 pro km und Passagier aus.\nEs haelt die Vorgaben ("+limitByLaw+") ein.";
        } else {
            result = "Dieses Auto stosst bei maximaler Passagierzahl ("+maxPassagiere+") "+checkLimit+"Gramm CO2 pro km und Passagier aus.\nEs haelt die Vorgaben ("+limitByLaw+") NICHT ein.";
        }
        return result;
    }
}

class LKW extends Benziner {
    int maxLadung;

    public LKW(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k, int maxLadung) {
        super(marke, modell, preis, anzahlRaeder, ps, maxGeschwindigkeit, tankSize, verbrauchPro100k);
        this.maxLadung = maxLadung;
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Dieser LKW kann "+maxLadung+" Tonnen laden.");
    }

    public String calculateAndEvaluateEmission (){
        double checkLimit = verbrauchPro100k/maxLadung ; //Vorarbeit um zu prüfen, ob dieses Auto die Grenzwerte einhält
        String result; //Variable für das Resultat der Evaluierung
        if (checkLimit<limitByLaw){
            result = "Dieser LKW stosst bei maximaler Beladung ("+maxLadung+" t) "+checkLimit+"Gramm CO2 pro km und Tonne aus.\nEs haelt die Vorgaben ("+limitByLaw+") ein.";
        } else {
            result = "Dieser LKW stosst bei maximaler Beladung ("+maxLadung+" t) "+checkLimit+"Gramm CO2 pro km und Tonne aus.\nEs haelt die Vorgaben ("+limitByLaw+") NICHT ein.";
        }
        return result;
    }
}

class Fahrrad extends Fahrzeug {
    double kalorienverbrauchProKm, gewicht;
    int anzahlGaenge;

    public void essen () {}

    public Fahrrad(String marke, String modell, double preis, int anzahlRaeder, double kalorienverbrauchProKm,
            double gewicht, int anzahlGaenge) {
        super(marke, modell, preis, anzahlRaeder);
        this.kalorienverbrauchProKm = kalorienverbrauchProKm;
        this.gewicht = gewicht;
        this.anzahlGaenge = anzahlGaenge;
    }
}

interface Carbon2OEmission {
    final double limitByLaw = 150; //Das steht für die Gramm CO2/km&Passagier, bzw. Gramm CO2/km&Tonne
    String calculateAndEvaluateEmission ();
}
Code:
Code der Klasse "Commands":

Java:
import java.util.*;

class Commands {

    //pseudo-Konstruktor. Damit die Methoden non-static sind...
    public Commands() {
        System.out.println("Commands-Instanz initialisiert!");
    }

    //Anzeigen aller bereits existierenden Objekte. zB für Optionen-Auswahl nötig
    public void showAllObjects () {
        for (int i=0; i<FindLength(); i++){
            if (fahrzeugArray[i]==null){
            } else {
                System.out.println(fahrzeugArray[i].toString());
            }
        }
    }
    public int FindLength (){return fahrzeugArray.length;}

    //Hier wählt der User ein Objekt aus, per int
    public int userChoosesObject () {
        System.out.println ("Folgende Fahrzeuge existieren schon:");
        showAllObjects(); //Auflistung aller existierenden Fahrzeuge, mit Nummer

        Scanner userChoosesObject = new Scanner (System.in);
        System.out.println ("\nWelches Fahrzeug willst du im nächsten Schritt bearbeiten?\nGib' die Nummer bitte 2-stellig an.");
        int usersChoice = userChoosesObject.nextInt();
        userChoosesObject.close();

        return usersChoice;
    }

    public void askUserForNextOperation () {
        Scanner askUserForNextOperation = new Scanner(System.in);
        int input=99;

        do {
            System.out.println("\nWillst du eine Funktion dieses Programms nutzen? Ja= 1, Nein=2");
            input = askUserForNextOperation.nextInt();
            if (input==1){
                proposeOptionstoUser();
            } if (input==2){
                System.out.println("\nGut, dann geht's zum folgenden Programmschritt.\nWenn da nix definiert ist, ist das das Ende.");
            }
        } while ((checkUserInput(2, input))==false);
    }

    public void proposeOptionstoUser () {
        Scanner proposeOptionstoUser = new Scanner (System.in);
        int input=99;
        do {
            System.out.println
            ("\nWillst du\n1: tanken\n2: fahren\n3: ein neues Fahrzeug generieren\n4: CO2-Ausstoss-Infos?");
            input = proposeOptionstoUser.nextInt();
    
            if (input==1){
               fahrzeugArray [userChoosesObject()].volltanken();
            }
            if (input==2) {
                System.out.println("Fahren wird gestartet");
                //fahren (); //geht nicht weil ich gerade in einer statischen Methode bin

            }
            if (input==3) {
                System.out.println("Generieren wird gestartet");
                //fahrzeugGenerieren (); //geht nicht weil ich gerade in einer statischen Methode bin
            }
            if (input==4) {
                System.out.println("Ausstoss wird berechnet");
            }
        }
        while ((checkUserInput(3, input))==false);
        askUserForNextOperation();
    }

    //Hier wird geprüft, ob die User-Eingabe mit den Anzahl Optionen übereinstimmt
    public boolean checkUserInput (int numberOfOptions, int userChoice){
        boolean userInputPossible;
        if (userChoice< (numberOfOptions+1)) {
            if (userChoice>0){
                userInputPossible = true;
            } else {
                System.out.println("Der eingebene Wert ist ungueltig.");
                userInputPossible = false;
            }
        } else {
            System.out.println("Der eingebene Wert ist ungueltig.");
            userInputPossible = false;
        }
        return userInputPossible;
    }
}
Vielen Dank für eure Hilfe, ich bin wirklich sehr dankbar dafür!
Gibt es eigentlich ne Möglichkeit, was zu spenden oä?

Gruss aus der Schweiz,
Markus
 
mrBrown

mrBrown

fahrzeugArray ist eine lokale Variable in der main-Methode, außerhalb existiert die also nicht. Was du machen kannst, ist das fahrzeugArray an Commands zu übergeben.

BTW: üblich ist, genau eine Top-Level-Class pro Datei zu haben, bei dir also alle Klassen in eine eigene Datei :)
 
Zuletzt bearbeitet:
M

MarkusFromBerne

So, mein Programm läuft einigermassen (und ich bin ein bisschen stolz 😊). Letztendlich hab' ich UserAbfragen etc doch wieder ins main genommen, war sonst zu umständlich.

Hier der Code für Interessierte:
Java:
import java.util.Scanner;

public class kapitel13a3main {

    Scanner scan = new Scanner (System.in);
    public static void main(String[] args) {
        Benziner [] benzinerArray = new Benziner [20];
        //Das Array ist halt mal fix auf 20 Elemente eingestellt. Klar wäre automatisch verlängern besser...
        // Ausserdem hatte ich Probleme mit Array, dass verschiedene Datentypen enthält. Object [] ging auch nicht

        //ein paar Fahrzeuge zum Testen
        Auto a1  = new Auto("Audi", "quattro", 12500, 4, 150, 210, 60, 4, 5);
        benzinerArray [0] = a1;
        LKW l1 = new LKW("Iveco", "longliner", 360000, 8, 300, 90, 250, 11, 30);
        benzinerArray [1] = l1;


        //Fahrrad v1 = new Fahrrad("Trek", "downhill", 2999, 2, 150, 12000, 21);
        //benzinerArray[2]=v1;

        //eigentlicher Start des Programms
        kapitel13a3main operationBase = new kapitel13a3main (); //das ist ein leeres Objekt, um die blöde static->non-static Geschichte zu beenden
        operationBase.askUserForNextOperation(benzinerArray);
        //Ende des Programms. Damit man weiss, dass es ordnungsgemäss zu Ende ist ;-)
        System.out.println("Ende des Programms");
    }

    //Anzeigen aller bereits existierenden Objekte. zB für Optionen-Auswahl nötig
    public void showAllObjects (Benziner [] benzinerArray) {
        for (int i=0; i<benzinerArray.length; i++){
            if (benzinerArray[i]==null){
            } else {
                System.out.println(i+": "+benzinerArray[i].marke+", Modell "+benzinerArray[i].modell);
            }
        }
    }

    //Auszählen der "belegten" Zellen im Array
    public int countElementsInArray (Benziner [] benzinerArray){
        int countElementsInArray=0;
        for (int i=0; i<benzinerArray.length; i++){
            if (benzinerArray[i]==null){
            } else {
                countElementsInArray++;
            }
        }
        System.out.println("Momentan hat es "+countElementsInArray+" (i=0-"+(countElementsInArray-1)+") Elemente im Array.");
        return countElementsInArray;
    }

    //Hier wählt der User ein Objekt aus, per int
    public int userChoosesObject (Benziner [] benzinerArray) {
        System.out.println ("\nFolgende Fahrzeuge existieren momentan:");
        showAllObjects(benzinerArray); //Auflistung aller existierenden Fahrzeuge, mit Nummer
        
        int usersChoice;
        do {
            System.out.println ("\nWelches Fahrzeug willst du im naechsten Schritt bearbeiten bzw. anschauen?");
            usersChoice=scan.nextInt();
        }   while (checkUserInput(countElementsInArray(benzinerArray), usersChoice)==false);

        return usersChoice;
    }

    //Abfrage wie User weiterfahren will
    public void askUserForNextOperation (Benziner [] benzinerArray) {

        int input=99;

        do {
            System.out.println("\nWillst du eine Funktion dieses Programms nutzen? Ja= 1, Nein=2");
            input=scan.nextInt();
            if (input==1){
                proposeOptionstoUser(benzinerArray);
            } if (input==2){
                System.out.println("\nGut, dann geht's zum folgenden Programmschrftt.\nWenn da nix definiert ist, ist das das Ende.");
            }
        } while ((checkUserInput(2, input))==false);
        
    }

    //Mögliche Operationen des Programs
    public void proposeOptionstoUser (Benziner [] benzinerArray)  {
        
        int input=99;
        double distance=0;

        do {
            System.out.println("Was willst du tun?\n"+
            "1: genaueres ueber ein bestimmtes Fahrzeug wissen\n"+
            "2: fahren\n"+
            "3: ein neues Fahrzeug generieren\n"+
            "4: CO2-Ausstoss-Infos\n"+
            "5: volltanken (geht nur fuer Benziner...)"+
            "?");
            input=scan.nextInt();
    
            if (input==1){
                benzinerArray[userChoosesObject(benzinerArray)].allInfosAboutTHISFahrzeug();
            }
            if (input==2) {
                int temp = userChoosesObject(benzinerArray);
                System.out.println("Dieses Fahrzeug hat momentan "+
                benzinerArray[temp].aktuellerTankstand+ " Liter im Tank."+
                "\nDamit kann es "+benzinerArray[temp].berechneReichweite()+ "km weit fahren.");
                do {
                    System.out.println("\nWie weit willst du fahren?\nGib realistische Werte ein...");
                    distance=scan.nextDouble();
                } while (benzinerArray[temp].berechneReichweite()<distance);

                benzinerArray[temp].fahren(distance);
            }
            if (input==3) {
                System.out.println("coming soon");
                //fahrzeugGenerieren (); //geht nicht weil ich gerade in einer statischen Methode bin
            }
            if (input==4) {
                System.out.println(benzinerArray[userChoosesObject(benzinerArray)].calculateAndEvaluateEmission());
            }
            if (input==5) {
                benzinerArray[userChoosesObject(benzinerArray)].volltanken();
            }
        }
        while ((checkUserInput(5, input))==false);

        askUserForNextOperation(benzinerArray);
    }

    //Hier wird geprüft, ob User-Eingaben mit den Anzahl Optionen übereinstimmen
    public boolean checkUserInput (int numberOfOptions, int userChoice){
        boolean userInputPossible;
        if (userChoice< (numberOfOptions+1)) {
            if (userChoice>=0){
                userInputPossible = true;
            } else {
                System.out.println("Der eingebene Wert ist ungueltig.");
                userInputPossible = false;
            }
        } else {
            System.out.println("Der eingebene Wert ist ungueltig.");
            userInputPossible = false;
        }
        return userInputPossible;
    }

}

class Fahrzeug{
    String marke, modell;
    double preis;
    int anzahlRaeder;

    public void fahren (double distance) {
        System.out.println("Aufruf der Fahren-Methode von class Fahrzeug");
    }

    public void allInfosAboutTHISFahrzeug (){
        System.out.println(
        "\nDas Modell "+modell+
        " der Marke "+marke+
        //Hier soll die Methode aufgerufen werden, die den ClassType bestimmt.
        " ist ein "+this.getClass().getSimpleName()+
        ".\nEs kostet "+preis+" Franken und hat "+anzahlRaeder+" Raeder.");
    }

    public Fahrzeug(String marke, String modell, double preis, int anzahlRaeder) {
        this.marke = marke;
        this.modell = modell;
        this.preis = preis;
        this.anzahlRaeder = anzahlRaeder;
    }

    @Override
    public String toString() {
        return "Fahrzeug [anzahlRaeder=" + anzahlRaeder + ", marke=" + marke + ", modell=" + modell + ", preis=" + preis
                + "]";
    }
}

abstract class Benziner extends Fahrzeug implements Carbon2OEmission{
    int ps, maxGeschwindigkeit;
    double verbrauchPro100k, Reichweite, aktuellerTankstand, tankSize;
    final double preisProLiterBenzin = 1.55;

    public void volltanken (){
        System.out.println("Momentan sind "+aktuellerTankstand+"Liter Benzin im Tank.\nDieser Tank kann "+tankSize+"Liter aufnehmen.\n");
        if (aktuellerTankstand>tankSize){
            System.out.println("Es kann nicht mehr Benzin im Tank sein als dessen Fassungsvermoegen.\nNaja, ich ignoriere das mal.");
        }
        System.out.println("Es werden "+(tankSize-aktuellerTankstand)+" Liter Benzin getankt."+
        "Das kostet "+((tankSize-aktuellerTankstand)*preisProLiterBenzin)+" Franken.");
       this.aktuellerTankstand=tankSize;
    }

    public Benziner(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k) {
        super(marke, modell, preis, anzahlRaeder);
        this.ps = ps;
        this.maxGeschwindigkeit = maxGeschwindigkeit;
        this.tankSize = tankSize;
        this.verbrauchPro100k = verbrauchPro100k;
        Reichweite = berechneReichweiteVollgetankt();
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Dieses Fahrzeug hat eine maximale Geschwindigkeit von "+maxGeschwindigkeit+
        " kmh und eine Leistung von "+ps+" PS.\nSein Tank fasst "+tankSize+
        " Liter, damit kann es bei einem Verbrauch von "+verbrauchPro100k+
        " L/100km "+Reichweite+
        " km weit fahren."
        );
    }

    public double berechneReichweite (){
        return Math.rint(((aktuellerTankstand/verbrauchPro100k)*100));
    }

    public double berechneReichweiteVollgetankt (){
        return Math.rint(((tankSize/verbrauchPro100k)*100));
    }

    public void fahren (double distance) {
        aktuellerTankstand=aktuellerTankstand-(distance*(verbrauchPro100k/100));
        System.out.println("Dieses Fahrzeug ist "+distance+" km gefahren und hat "+(distance*(verbrauchPro100k/100))+" Liter Benzin verbraucht.\nJetzt sind noch "+aktuellerTankstand+" Liter im Tank.");
    }
}

class Auto extends Benziner {
    int maxPassagiere;

    public Auto(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k, int maxPassagiere) {
        super(marke, modell, preis, anzahlRaeder, ps, maxGeschwindigkeit, tankSize, verbrauchPro100k);
        this.maxPassagiere = maxPassagiere;
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Maximal "+maxPassagiere+" Passagiere passen in dieses Auto.");
    }

    public String calculateAndEvaluateEmission (){
        double checkLimit = verbrauchPro100k/maxPassagiere ; //Vorarbeit um zu prüfen, ob dieses Auto die Grenzwerte einhält
        String result; //Variable für das Resultat der Evaluierung
        if (checkLimit<limitByLaw){
            result = "\nDieses Auto stosst bei maximaler Passagierzahl ("+maxPassagiere+") "+checkLimit+"Gramm CO2 pro km und Passagier aus.\nEs haelt die Vorgaben ("+limitByLaw+"g/km) ein.";
        } else {
            result = "\nDieses Auto stosst bei maximaler Passagierzahl ("+maxPassagiere+") "+checkLimit+"Gramm CO2 pro km und Passagier aus.\nEs haelt die Vorgaben ("+limitByLaw+"g/km) NICHT ein.";
        }
        return result;
    }

    public void fahren (double distance) {super.fahren(distance);}
    public void volltanken (){super.volltanken ();}
}

class LKW extends Benziner {
    int maxLadung;

    public LKW(String marke, String modell, double preis, int anzahlRaeder, int ps, int maxGeschwindigkeit,
            double tankSize, double verbrauchPro100k, int maxLadung) {
        super(marke, modell, preis, anzahlRaeder, ps, maxGeschwindigkeit, tankSize, verbrauchPro100k);
        this.maxLadung = maxLadung;
    }

    public void allInfosAboutTHISFahrzeug (){
        super.allInfosAboutTHISFahrzeug();
        System.out.println("Dieser LKW kann "+maxLadung+" Tonnen laden.");
    }

    public String calculateAndEvaluateEmission (){
        double checkLimit = verbrauchPro100k/maxLadung ; //Vorarbeit um zu prüfen, ob dieses Auto die Grenzwerte einhält
        String result; //Variable für das Resultat der Evaluierung
        if (checkLimit<limitByLaw){
            result = "\nDieser LKW stosst bei maximaler Beladung ("+maxLadung+" t) "+checkLimit+"Gramm CO2 pro km und Tonne aus.\nEs haelt die Vorgaben ("+limitByLaw+"g/km) ein.";
        } else {
            result = "\nDieser LKW stosst bei maximaler Beladung ("+maxLadung+" t) "+checkLimit+"Gramm CO2 pro km und Tonne aus.\nEs haelt die Vorgaben ("+limitByLaw+"g/km) NICHT ein.";
        }
        return result;
    }

    public void fahren (double distance) {super.fahren(distance);}
    public void volltanken (){super.volltanken ();}
}

class Fahrrad extends Fahrzeug {
    double kalorienverbrauchProKm, gewicht;
    int anzahlGaenge;

    public void essen () {}

    public Fahrrad(String marke, String modell, double preis, int anzahlRaeder, double kalorienverbrauchProKm,
            double gewicht, int anzahlGaenge) {
        super(marke, modell, preis, anzahlRaeder);
        this.kalorienverbrauchProKm = kalorienverbrauchProKm;
        this.gewicht = gewicht;
        this.anzahlGaenge = anzahlGaenge;
    }

    public void fahren (double distance) {
        System.out.println("Juhui, du bist "+distance+"km weit gefahren!"+
        "Später kommt dann noch ne essen-Funktion dazu.");
    }
}

interface Carbon2OEmission {
    final double limitByLaw = 150; //Das steht für die Gramm CO2/km&Passagier, bzw. Gramm CO2/km&Tonne
    String calculateAndEvaluateEmission ();
}
Danke an alle für Eure Hilfe!
Gruss aus Bern,
Markus
 
M

MarkusFromBerne

Nur ein Scanner, der mit System.in arbeitet, sollte für das gesamte Programm genutzt werden. Den kannst du dann überall nutzen – wobei man das idealerweise eng begrenzt.


Ne, Scanner ist eine Klasse, und davon erstellst du ein Objekt, auf dem du Methoden aufrufst :)
Ich hab' ne Weile gebraucht, bis ich gecheckt habe, dass der Scanner ausserhalb der main aufgerufen werden muss, damit er überall nutzbar ist ;)
Danke für die Erläuterung.
 
Thema: 

konzeptuelle Frage: In welcher Klasse definiert man am Besten Methoden, die die Kommunikation mit dem User regeln?

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben