# Auto fahren in Java



## Jannis17 (10. Okt 2011)

Hey ich muss für die Schule diese Folge durcharbeiten: BlueJ-Lehrgang von Ulrich Helmich, Folge 4.

Ich habe gerade mit Java angefangen und wollte mal von Leuten die es besser wissen, hören ob meine Lösung richtig bzw umständlich ist.
Ich hoffe es findet sich vielleicht jemand der sich die Mühe macht und mal einen Blick drauf wirft.

Manche if Bedingungen sind noch nicht fertig, aber das werde ich später machen. Wichtig ist mir jetzt erstmal was ich am bestehenden Code verbessern könnte.



```
public class Auto
{
    double tankvolumen, benzinstand;
    double verbrauch;
    double kmstand;
    double leergewicht;
    double zulgesamtgewicht;
    double person1;
    double person2;
    double person3;
    double person4;
    double gepaeck;
    double verbrauch2;
    double gewicht;
    double gesgewicht;
        
public Auto(double tv, double bst, double verb, double km, double leer, double zulges, double p1, double p2, double p3, double p4, double gep)
{
tankvolumen = tv;
benzinstand = bst;
verbrauch = verb;
kmstand = km;
leergewicht = leer;
zulgesamtgewicht = zulges;
person1 = p1;
person2 = p2;
person3 = p3;
person4 = p4;
gepaeck = gep;
}

public void tanken(double liter)
{

benzinstand = benzinstand + liter;

if(benzinstand > tankvolumen) {
//Tu was 
}


}

public void fahren(double kilometer)
{
kmstand = kmstand + kilometer;
gewicht = person1 + person2 + person3 + person4 + gepaeck;
gesgewicht = gewicht + leergewicht; 
verbrauch2 = verbrauch * gesgewicht/500;
benzinstand = benzinstand - kilometer/100 * verbrauch2;

if(zulgesamtgewicht < gesgewicht) {
// Tu Was
}

if(benzinstand == 0) {
//Tu was
}

}


public void anzeigen()
{
gewicht = person1 + person2 + person3 + person4 + gepaeck;
gesgewicht = gewicht + leergewicht;
verbrauch2 = verbrauch * gesgewicht/500;

System.out.print("\f");
System.out.println("Tankvolumen = "+tankvolumen+" Liter");
System.out.println("Benzinstand = "+benzinstand+" Liter");
System.out.println("Verbrauch bei Leergewicht = "+verbrauch+" Liter/100km");
System.out.println("Verbrauch aktuell = "+verbrauch2+" Liter/100km");
System.out.println("Leergewicht = "+leergewicht+" kg");
System.out.println("Geladenes Gewicht = "+gewicht+" kg");
System.out.println("Gesamtgewicht = "+gesgewicht+" kg");
System.out.println("Zul. Gesamtgewicht = "+zulgesamtgewicht+" kg");
System.out.println("Km-Stand = "+kmstand+" km");
}

}
```

Vielen Dank


----------



## Final_Striker (10. Okt 2011)

Da sich weder die Gewichte oder der Verbrauch deines Autos ändern, macht es keinen Sinn diese ständig neu zu berechnen.


```
gewicht = person1 + person2 + person3 + person4 + gepaeck;
gesgewicht = gewicht + leergewicht;
verbrauch2 = verbrauch * gesgewicht/500;
```


----------



## Jannis17 (10. Okt 2011)

Ok ich kann diese Zeilen also aus meiner ausgabe Methode streichen.
Gibt es sonst noch etwas ?! Vielen Dank schonmal


----------



## Firephoenix (10. Okt 2011)

Hi,
ob die Attribute alle double sein müssen sei mal dahingestellt 

zu tanken:
hier macht es evtl sinn die abfrage erst zu machen und dannach nur soviel zu tanken wie reinpasst.
An der Tankstelle füllst du ja auch nicht erstmal 200 Liter in dein Mofa bis du merkst dass zuviel drin ist 

zu fahren:
wenn ein Auto fährt bewegt es sich, in der Zwischenstrecke ist es unwahrscheinlich, dass Toni und Alfred auf dem Rücksitz sich soviel Donuts reingefuttert haben, dass sich das Wagengewicht derart verlagert, dass dies Auswirkungen auf das Fahrverhalten hätte. Daher: fahren sollte auch nur parameter ändern die mit fahren zu tun haben.
Auch hier gehört aber die Abfrage vor die eigentliche Methode (Das Auto fährt nicht erstmal 100 Meter bis es merkt, dass es zu schwer war um den Hang dazwischen zu schaffen)

anzeigen passt so, ist ja schließlich auch nur eine Anzeige 

Weitere späße wie getter/setter findest du wohl von alleine, falls du die in der Klasse noch brauchst (ebenso wie die Access Modifier)
Gruß


----------



## jfg (10. Okt 2011)

Die Klasse ist entwurfsmäßig ziemlich "naja" ...

1. Viel zu viele Konstruktor-Parameter! Außerdem macht die Hälfte schlichtweg keinen Sinn. Oder werden Autos neuerdings inklusive Personen  und Gepäck hergestellt? Besonders der Teil mit den Personen hört sich arg nach Science Fiction an ... Autos mit Roboter-Chauffeur oder so ähnlich. Und das mit dem KM-Stand und der Tankfüllung ist auch stark diskussionswürdig.

2. Die Hälfte der Attribute sind keine Variablen sondern vielmehr Konstanten. Das wird allerdings von deinem Klassendesign ignoriert.

3. Wo ist in der Methode tanken() die Überprüfung, ob es überhaupt in den Tank passt?

4. fahren() fährt erstmal 500 km los, rechnet das Gewicht des Fahrzeugs aus (??) und schaut irgendwann am Ende ob überhaupt noch Sprit da war. Stilecht natürlich mit negativem Füllstand am Ende. So ein geniales Fahrzeug würde ich in der Tat mal gerne haben ...

5. Es liegt normalerweise nicht im Verantwortsbereich von Objekten, sich selbst anzuzeigen. Aber dieses Entwurfsdetail fällt gegenüber den anderen Wunderlichkeiten eigentlich gar nicht mehr ins Gewicht.


----------



## Jannis17 (10. Okt 2011)

Ich würde es ja auch anders machen ... ich weiß selber das da keine Main Methode etc drin steht und der Konstruktur viel zu viele Parameter hat aber wenn du mal auf den von mir oben gepusteten Link schausts dann wirst du sehen das genau das verlangt wird oder nicht ?
Wie würde ich es besser machen ?
Danke


----------



## jfg (10. Okt 2011)

Eine Main-Methode hätte da auch schlicht und einfach nichts verloren.

OK, ein paar konstruktive Vorschläge:

1. Beschränke deine Konstruktor-Parameter auf diejenigen, die du für ein _technisch gesehen funktionstüchtiges_ Auto benötigst. Den ganze Zusatzkram wie Personen, Gepäck und Sprit kannst du immer noch nachträglich über entsprechende Methoden hinzufügen. Bei der Objekterzeugung wird er hingegen mit null (Objekte) bzw. 0 (KM-Stand, Tankfüllung) initialisiert.

2. Personen sind Personen, also eigene Klassen, und keine double-Werte. Personen haben neben anderen Attributen auch ein Gewicht.

3. Überdenk die logische Reihenfolge in deinen Methoden. Es ist sinnfrei, erst etwas zu machen, und anschließend zu prüfen, ob man das überhaupt machen konnte. Und bei Sachen wie dem Befüllen eines Tanks reicht es bereits, einfach mal mit gesundem Menschenverstand ranzugehen. Denn überlege dir selbst: Was passiert, wenn du in einen halbvollen Tank eine ganze Tankfüllung nachkippen willst?
a. Es geht von Anfang an nicht und der Tank bleibt halb voll.
b. Es geht und der Tank ist 1,5 mal voll.
c. Der Tank ist voll und der Rest schwappt über.
Wie du siehst, kann du auch (bzw. gerade) in der Objektorientierung vieles bereits mit gesundem Menschverstand herleiten.

4. Die Berechnung des Gesamtgewichts in eine eigene Methode auslagern.


----------



## Jannis17 (11. Okt 2011)

Ok hab es nun nochmal versucht zu verbessern..
Meinst du ungefähr so ?

Auto Klasse:

```
import javax.swing.JOptionPane;
public class Auto
{
    double tankvolumen,benzinstand,verbrauch,kmstand;
    double leergewicht,zulgesamtgewicht,verbrauch2,gesgewicht,gewicht;

    Person p1 = new Person();
    Person p2 = new Person();
    Person p3 = new Person();
    Person p4 = new Person();
    Gepäck g1 = new Gepäck();

    public Auto(double tv, double bst, double verb, double km)
    {
        tankvolumen = tv;
        benzinstand = bst;
        verbrauch = verb;
        kmstand = km;

        leergewicht = 500;
        zulgesamtgewicht = 1000;

        p1.setGewicht(90);
        p2.setGewicht(84);
        p3.setGewicht(66);
        p4.setGewicht(87);
        g1.setGewicht(156);

    }

    public void tanken(double liter) {
        if(benzinstand > tankvolumen) {
            JOptionPane.showMessageDialog(null,"So viel können sie nicht tanken.","Tankvolumen überschritten",JOptionPane.WARNING_MESSAGE);
            benzinstand = tankvolumen;
        }
        else {
            benzinstand = benzinstand + liter;
        }
    }

    public void fahren(double kilometer) {
        if(benzinstand == 0) {
            JOptionPane.showMessageDialog(null,"Benzin ist leer !","Bitte tanken",JOptionPane.WARNING_MESSAGE);
        }

        if(zulgesamtgewicht < gesgewicht) {
            JOptionPane.showMessageDialog(null,"Sie sind zu schwer.","Zulässiges Gewicht überschritten",JOptionPane.WARNING_MESSAGE);
        }
        kmstand = kmstand + kilometer;
        verbrauch2 = verbrauch * gesamtGewicht()/500;
        benzinstand = benzinstand - kilometer/100 * verbrauch2;
    }

    private double gesamtGewicht() {

        gewicht = p1.getGewicht()+p2.getGewicht()+p3.getGewicht()+p4.getGewicht()+g1.getGewicht();
        gesgewicht = leergewicht+gewicht;

        return gesgewicht;
    }

    public void anzeigen()
    {
        System.out.print("\f");
        System.out.println("Tankvolumen = "+tankvolumen+" Liter");
        System.out.println("Benzinstand = "+benzinstand+" Liter");
        System.out.println("Verbrauch bei Leergewicht = "+verbrauch+" Liter/100km");
        System.out.println("Verbrauch aktuell = "+verbrauch2+" Liter/100km");
        System.out.println("Leergewicht = "+leergewicht+" kg");
        System.out.println("Geladenes Gewicht = "+gewicht+" kg");
        System.out.println("Gesamtgewicht = "+gesgewicht+" kg");
        System.out.println("Zul. Gesamtgewicht = "+zulgesamtgewicht+" kg");
        System.out.println("Km-Stand = "+kmstand+" km");
    }
}
```

Personen Klasse:


```
public class Person
{

    double gewicht;
  
    public Person()
    {

    }
    
    public void setGewicht(double d) {
        this.gewicht = d;
    }
    
    public double getGewicht() {
        return gewicht;
    }
   

}
```

Gepäck Klasse:

```
public class Gepäck
{

    double gewicht;
  
    public Gepäck()
    {

    }
    
    public void setGewicht(double d) {
        this.gewicht = d;
    }
    
    public double getGewicht() {
        return gewicht;
    }
   

}
```

Wäre sehr dankbar für eine Rückmeldung, danke !


----------



## Jannis17 (11. Okt 2011)

Keiner ? Wäre mir wirklich wichtig das ich am ende hier eine gute Lösung habe, denn ich möchte das ja auch lernen.
Ihr seht ja das ich bereit bin eure Tipps anzunehmen und versuche meinen Code weitesgehend nach euren Ratschlägen umzusetzen, es wäre nur toll, wenn mir nun jemand sagen könnte ob mir das auch gelungen ist, oder ob ich da Mist verzapft hab. 

Vielen Dank
Gruß
Jannis


----------



## Blakh (11. Okt 2011)

Sowohl die fahren-Methode als auch die tanken-Methode enthalten logische Fehler.

z.B. : 
	
	
	
	





```
public void tanken(double liter) {
        if(benzinstand > tankvolumen) {
            JOptionPane.showMessageDialog(null,"So viel können sie nicht tanken.","Tankvolumen überschritten",JOptionPane.WARNING_MESSAGE);
            benzinstand = tankvolumen;
        }
        else {
            benzinstand = benzinstand + liter;
        }
    }
```

Du prüfst zuerst, ob der aktuelle Benzinstand größer als das Tankvolumen ist. Stell dir vor... du fährst tanken. Du kommst an und stellst fest... hmm.. ich hab mehr Benzin im Tank, als ich überhaupt haben darf. Also zauberst du dann einfach das überschüssige Benzin weg. Wenn du aber noch 1 Liter tanken kannst vom Tankvolumen her, dann kannst du munter einfach 100 Liter einfüllen.
Bei der fahren-Methode ist es analog.


----------



## timbeau (11. Okt 2011)

Frei nach Motto Autopilot: "Sie können maximal 35Liter tanken. Wieviel möchten Sie tanken?"

"50 Liter";

"Nein, 50Liter können Sie NICHT tanken! Sie können maximal 35Liter tanken! Wieviel möchten Sie tanken?"

"45 Liter"

"Idiot!"


----------



## dehlen (11. Okt 2011)

Edit: schwachsinn


----------



## Blakh (11. Okt 2011)

Naja... stell dir vor (gg*) ... du hast 1 Liter im Tank. Deine Tankanzeige sagt dir...gut Tank ist nicht leer.... also fährst du 10000 Kilometer mit einem Liter Benzin . Lass dir doch bei der Methode einfach die tatsächlich gefahrene Strecke zurückgeben. Nur 1 Liter Benzin? Dann fährt die Karre halt nur noch 10 Kilometer.


----------



## Jannis17 (11. Okt 2011)

Ok habe die tanken Methode nun so geändert:

```
public void tanken(double liter) {
        if(benzinstand+liter>tankvolumen) {
             JOptionPane.showMessageDialog(null,"So viel Benzin fasst ihr Tank nicht !","Weniger Tanken",JOptionPane.WARNING_MESSAGE);;
            }
            else benzinstand += liter;
        }
```

fahren habe ich nun so:

```
public void fahren(double kilometer) {
         if(benzinstand == 0 ||*zulgesamtgewicht < gesgewicht ) {
            JOptionPane.showMessageDialog(null,"Überprüfen sie bitte den Tank und das sie nicht das zulässige Gewicht überschreiten","Fahren unmöglich",JOptionPane.WARNING_MESSAGE);
        }
         else {
        kmstand = kmstand + kilometer;
        benzinstand -= kilometer/100 * verbrauch*gesamtGewicht()/500;
    }
    }
```

ist das jetzt richtig ? kann ich das so machen mit den gettern und Settern wegen den Personen und dem Gepäck ? gehört das in den Konstruktor ? Danke


----------



## Jannis17 (11. Okt 2011)

Ok habe gerade erst deinen Kommentar gesehen, das heißt meine fahren Methode ist immer noch falsch... jetzt habe ich aber auch gerafft wieso  Naja hast du noch Antworten auf die anderen Fragen von meinem vorherigen Post ?
Ich versuche mal die fahren Methode nun richtig zu implementieren


----------



## Jannis17 (11. Okt 2011)

ok ich komm einfach nicht drauf... ich denke ich bin einfach noch zu "unerfahren" mit dem Design von Java Klassen. Es wäre super wenn mir hier jemand vielleicht eine "Musterlösung" aufzeigen könnte. Ich weiß es wäre besser wenn ich selbst drauf kommen würde, doch ich finde man lernt auch immer in dem man sich Beispiele anguckt und versucht zu verstehen. Es wäre wie gesagt toll wenn hier jemand mir mal eine Lösung präsentieren könnte. 

Vielen Dank trotzdem bis hierhin, wirklich tolles Forum !


----------



## timbeau (11. Okt 2011)

Kein Problem 

Aber grundsätzlich meinst du, du hast die Problematik verstanden? Durch fertige Lösungen lernt man mE sehr wenig/schlecht. 

Dein Problem ist, dass du vorher überlegen musst, ob dein Tank für die gewollte Strecke (double kilometer) überhaupt reicht. 
Bsp: Sagen wir du hast 30Liter im Tank. Dein Verbrauch liegt bei 7l/100km. Wie weit kommst du? 
Ungefähr 430km. 

Jetzt kannst du überlegen, ob dein Auto dann maximal soweit fährt, ob du den Vorgang abbrichst, eine Warnung ausgibst usw.


----------



## Jannis17 (11. Okt 2011)

ok und grundsätzlich diese Klassen Person und Gepäck mit den gettern und Settern ist das vom Design her richtig ?
Ist es richtig das ich das Gewicht der Personen und des Gepäcks in dem Konstruktor setze ?
Ist die tanken Methode richtig ?
Sollte ich die fahren Methode also so aufbauen ?

```
if(zulässiges Gewicht ist kleiner als das momentane Gewicht) {
fahr gar nicht erst los;
}
if(tank reicht nicht aus um angegebene km zu fahren) {
dann fahr nur soviel wie möglich und sag das dem Anwender
}

if(tank ist leer) {
fordere zum tanken auf
}
else {
fahre die angegebenen kilometer
}
```


----------



## timbeau (11. Okt 2011)

Die Gepäck + Personenklassen solltest du eventuell umformulieren:


```
public class Person {
	double gewicht;
	  
    public Person(double gewicht)
    {
    	this.gewicht = gewicht;
    }
    
    public void setGewicht(double d) {
        this.gewicht = d;
    }
    
    public double getGewicht() {
        return gewicht;
    }
}
```
 unter dem Gedankenpunkt, dass eine Person in so einem Fall ein Gewicht von Anfang bis Ende der Fahrt hat und nicht groß ändert. Natürlich kann man die Setter-Methode auch drin lassen. Aber um zu verhindern, dass du eine Person ohne Gewicht erschaffst, lieber im Konstruktor. 

Ich gebe dir noch ein Paar Gedankengänge/Reale Szenarien:

Personen steigen aus/ein. Wieviele dürfen rein?
Gepäck raus/rein. 

Personen eventuell gruppieren in einer Liste.
Gepäckstücke analog. 

Kann über setter-Methoden gemacht werden, die die Personen setzen bzw. entfernen. 

Die Tanken-Methode kann man so machen. Du kannst auch eine Methode entwerfen, die die maximal-mögliche Tankmenge zurückgibt und immer soviel tanken, wenn zuviel getankt werden soll. Ich mein, ich kann auch für 500€ am Kreditkartenautomat tanken und wenn mein Tank voll ist, stoppt das Teil automatisch und berechnet mir den tatsächlichen Preis.


----------



## Jannis17 (11. Okt 2011)

Ok ich denke ich habs nun ) Hier mal meine aktuelle version:


```
import javax.swing.JOptionPane;
import java.text.DecimalFormat;
public class Auto
{
    double tankvolumen,benzinstand,verbrauch,kmstand;
    double leergewicht,zulgesamtgewicht,verbrauch2,gesgewicht,gewicht,fahrbareStrecke;

    Person p1 = new Person();
    Person p2 = new Person();
    Person p3 = new Person();
    Person p4 = new Person();
    Gepäck g1 = new Gepäck();

    public Auto(double tv, double bst, double verb, double km)
    {
        tankvolumen = tv;
        benzinstand = bst;
        verbrauch = verb;
        kmstand = km;

        leergewicht = 500;
        zulgesamtgewicht = 1000;

        p1.setGewicht(90);
        p2.setGewicht(84);
        p3.setGewicht(66);
        p4.setGewicht(87);
        g1.setGewicht(156);

    }

    public void tanken(double liter) {
        if(benzinstand+liter > tankvolumen) {
            JOptionPane.showMessageDialog(null,"So viel können sie nicht tanken.","Tankvolumen überschritten",JOptionPane.WARNING_MESSAGE);
            benzinstand = tankvolumen;
        }
        else {
            benzinstand = benzinstand + liter;
        }
    }

    public void fahren(double kilometer) {
        verbrauch2 = verbrauch*gesamtGewicht()/500;
        fahrbareStrecke = benzinstand/verbrauch2 *100;
        DecimalFormat format = new DecimalFormat("#.##"); 

        if(benzinstand == 0) {
            JOptionPane.showMessageDialog(null,"Benzin ist leer !","Bitte tanken",JOptionPane.WARNING_MESSAGE);
        }

        else if(zulgesamtgewicht < gesgewicht) {
            JOptionPane.showMessageDialog(null,"Sie sind zu schwer.","Zulässiges Gewicht überschritten",JOptionPane.WARNING_MESSAGE);
        }
        
        else if(fahrbareStrecke < kilometer) {
            JOptionPane.showMessageDialog(null,"Das Benzin reicht nicht für die angegebene Strecke aus. Das Auto kann maximal "+format.format(new Double(fahrbareStrecke))+"km damit fahren","Nicht genug Benzin!",JOptionPane.WARNING_MESSAGE);
        }
        
        
       else { kmstand = kmstand + kilometer;
        benzinstand = benzinstand - kilometer/100 * verbrauch2;
    }
    }

    private double gesamtGewicht() {

        gewicht = p1.getGewicht()+p2.getGewicht()+p3.getGewicht()+p4.getGewicht()+g1.getGewicht();
        gesgewicht = leergewicht+gewicht;

        return gesgewicht;
    }

    public void anzeigen()
    {
        System.out.print("\f");
        System.out.println("====================================");
        System.out.println("Gewicht von den Personen und dem Gepäck, sowie das Leergewicht und das\nzulässige Gesamtgewicht wurden im Konstruktor von vorne herein festgelegt!");
        System.out.println("====================================");
        System.out.println("Tankvolumen = "+tankvolumen+" Liter");
        System.out.println("Benzinstand = "+benzinstand+" Liter");
        System.out.println("Verbrauch bei Leergewicht = "+verbrauch+" Liter/100km");
        System.out.println("Verbrauch aktuell = "+verbrauch2+" Liter/100km");
        System.out.println("Leergewicht = "+leergewicht+" kg");
        System.out.println("Geladenes Gewicht = "+gewicht+" kg");
        System.out.println("Gesamtgewicht = "+gesgewicht+" kg");
        System.out.println("Zul. Gesamtgewicht = "+zulgesamtgewicht+" kg");
        System.out.println("Km-Stand = "+kmstand+" km");
    }
}
```

Personen und Gepäck sind noch gleich.

Sofern das richtig ist werde ich mich mal an



> Personen steigen aus/ein. Wieviele dürfen rein?
> Gepäck raus/rein.
> 
> Personen eventuell gruppieren in einer Liste.
> ...


versuchen, auch wenn das nicht mehr gefragt ist.

Danke )


----------



## timbeau (11. Okt 2011)

Ich verstehe nicht so ganz wie du verbrauch2 errechnest?!

Sagen wir der Standard Verbrauch sind 10l & wiegt 1000kg. 

1 Fahrer mit 70kg :

10 * 1070 / 500 = 21,4l

Sicher? Eher 10 * (1070 - 1000) / 500 = 1,4l Mehrverbrauch / 100km

Aber ich würde eher überlegen, ob ich nicht einfach pro 100kg 1l dazurechne. 

Bsp: 


```
int v = 10;
		int gewicht = 1000;
		int aktgewicht = 1170;
		int mehrVerbrauchPro100kg = 1;
		System.out.println(v + (mehrVerbrauchPro100kg  * ((aktgewicht - gewicht)  / 100)));
```


----------



## Jannis17 (11. Okt 2011)

Ja die Formel ist mehr willkürlich in der Aufgabenstellung steht:


> Für den Benzinverbrauch muss eine Formel entwickelt werden, bei der der Verbrauch pro 100 km mit dem Gesamtgewicht steigt.



Mehr nicht... 
daher hatte ich das jetzt mal so realisiert... die Formel kann ich ja aber auch noch ändern... 
Trotzdem der Rest läuft ja soweit denke ich mal korrekt ?! von daher bin ich schonmal glücklich


----------



## timbeau (11. Okt 2011)

Jo, ist doch super. BTW, würde ich nebenbei direkt mit JUnit anfangen. 

JUnit

bzw.

JUnit


----------



## Jannis17 (11. Okt 2011)

Ok habe gerade deine Berechnung zum Verbrauch bei mir eingebaut... das erscheint mir etwas realistischer.
Danke  
Ansonsten denke ich ist das Thema hier erledigt. Die Aufgaben die ich machen sollte habe ich ja nun alles weitere kann ich ja implementieren wenn ich Lust habe


----------

