Forum: PC-Programmierung Java Klassen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von JavaAnfänger (Gast)


Lesenswert?

Hallo, ich bin gerade dabei mich weiter bei Java einzuarbeiten. Momentan 
hänge ich an Klassen fest bzw eine Klasse mit einzelnen Methoden.

Ich würde gerne einen Tank für ein Auto programmieren.



Ich erstelle eine Klasse mit Drei Attributen:
groesse, fuellstand, verbrauch
1
public class Autotank {
2
//Eigenschaften des Autotanks:
3
  
4
  double groesse;
5
  double fuellstand;
6
  double verbrauch;

Einen Konstruktor mit drei Parameter für die Anfangswerte der Attribute:
1
// Konstruktor mit drei Parametern für die Anfangswerte der Attribute  
2
  public Autotank (double a, double b, double c){
3
    
4
    a = groesse;
5
    b = fuellstand;
6
    c = verbrauch;
7
  }

Nun möchte ich die fünf methoden realiseren:
fuellstand() und verbrauch() (Methoden sollen zurückliefern wieviel 
Liter benzin der Tank enthält bzw. wieviel Liter pro 100 km verbraucht 
werden.
1
//Methoden: fuellstand, verbrauch, tanken, fahren, reichweite:
2
  public double fuellstand(double fuellstand){
3
    return fuellstand;
4
  }
5
  
6
  public double verbrauch (double verbrauch){
7
    return verbrauch;
8
  }

tanken(): Möchte eine Nachkommastelle als Parameter übergeben, die 
angibt wieviel Liter getankt werden soll. Wenn die Zahl negativ ist, 
soll nichts passieren, wenn der Tank "Überlaufen" würde, so soll nur 
gefüllt werden, wie groß seine "groesse" ist.

fahren(): integer wert übergeben die angibt wieviel Km ich zurücklege. 
Tankinhalt soll geändert werden. Ist die Kilometerzahl negativ so soll 
nichts passieren. Ist die Zahl höher als der Tankinhalt so soll 
Tankinhalt auf 0 gesetzt werden. Ist der Tankinhalt 0 dann false als 
Rückgabewert ansonsten true.

reichweite (): soll berechnen wieviel KM das auto zurück legen könnte 
aufgrund von Tankinhalt und Verbrauch.


Fragen:
Kann ich die ersten beiden Methoden so schreiben? Ich weiß einfach 
nicht, wie ich die anderen 3 Methoden realiseren kann. Hilfestellung 
wäre super.

Danke

von Speckbert (Gast)


Lesenswert?

Bis wann muss die Hausaufgabe denn fertig sein?

von nicht"Gast" (Gast)


Lesenswert?

Wozu muss ein ein Tank über den Verbrauch bescheid wissen?

von Mark B. (markbrandis)


Lesenswert?

> double verbrauch;

Der Verbrauch ist keine Eigenschaft des Tanks. Er ist abhängig vom 
Motor, der Fahrweise, der Zuladung.

von JavaAnfänger (Gast)


Lesenswert?

31.01

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

1. Die Zuweisungen im Konstruktor sind falsch herum, muss z.B. 
groesse=a; heissen.

2. Die Attribute groesse, fuellstand und verbrauch sollten zusätlich 
"private" sein.

3. die Methoden zum Setzen und Auslesen ("Setter" u. "Getter") dürfen 
nicht (und sollten auch nicht) genau so heissen wie die Attribute, 
sondern z.B. GetFuellstand() ...

von Lang (Gast)


Lesenswert?

Kleiner Tip:

Was macht bzw wie funktioniert der Zuweisungsoperator =   ?

Vor Klassen nochmal lesen, wie Funktionen/Methoden definiert werden. In 
all den unterschiedlichen Ausprägungen.

Dann kommt man auf des Rätsels Lösung.

von JavaAnfänger (Gast)


Lesenswert?

Bin mir gerade nochmal alles von Anfang an am angucken.
1
public class Autotank {
2
  private static double groesse= 0;
3
  private static double fuellstand= 0;
4
  private double verbrauch= 0;
5
  
6
// Konstruktor mit drei Parametern für die Anfangswerte der Attribute  
7
  public Autotank (double a, double b, double c){
8
    
9
    groesse = a ;
10
    fuellstand = b;
11
    verbrauch = c;
12
  }
13
  //Methoden: fuellstand, verbrauch, tanken, fahren, reichweite:
14
//liefert den aktuellen Stand des Tankes
15
    public double getfuellstand(){
16
      return fuellstand;
17
    }
18
//liefert den Verbrauch des Autos    
19
    public double getverbrauch (){
20
      return verbrauch;
21
    }
22
//Methode zum ändern des Fuellstandes  
23
    public static void tanken (int liter){
24
      if(liter<=0 || fuellstand + liter > groesse){
25
      }else{
26
        fuellstand = fuellstand + liter;
27
    }
28
    }

Was ich nur nicht verstehe, ist warum ich die Variablen private sein 
müssen und static? Kann mir bitte jemand das bitte mit eigenen Worten 
erklären ?

von Mark B. (markbrandis)


Lesenswert?

JavaAnfänger schrieb:
> Was ich nur nicht verstehe, ist warum ich die Variablen private sein
> müssen und static?

Sie müssen nicht private sein. Es ist aber sinnvoll, wenn sie es sind. 
Stichwort: Datenkapselung. Anderer Code von außerhalb dieser Klasse soll 
die Werte der Objekte nur auf diejenige Art und Weise manipulieren 
können, welche die Klasse selbst vorsieht.

static ist hier nicht sinnvoll. Jedes Exemplar eines Tanks hat seinen 
eigenen Füllstand. Siehe auch:

http://www.javatpoint.com/static-keyword-in-java

: Bearbeitet durch User
von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Ein Attribut oder eine Methode macht man "static", wenn man sie benutzen 
will, ohne dass man dazu ein Objekt der Klasse instantiiert. Beispiel 
wäre eine Mathematik-Funktion aus der Math-Klasse.

Man kann z.B. a=Math.sin(b); benutzen, ohne vorher Math mit new erzeugt 
zu haben. Ist in deinem Beispiel aber nicht sinnvoll.

Ach ja - nochwas: Die Schreibweise.

Es hat sich in Java-Kreisen eine gewisse Schreibweise eingebürgert. Die 
ist zwar nicht technisch zwingend notwendig. "getfuellstand()" 
funktioniert genau so wie "GetFuellstand()" ... aber üblich wäre 
Letzters. Auch für die Benennung von Attributen und Klassen gibts solche 
Regeln. Wäre von Vorteil, wenn du dich gleich von Anfang an daran 
gewöhnst.

: Bearbeitet durch User
von foo (Gast)


Lesenswert?

Frank E. schrieb:
> "getfuellstand()"
> funktioniert genau so wie "GetFuellstand()" ... aber üblich wäre
> Letzters.

Nein. Üblich wäre getFuellstand().
CamelCase mit Majuskel vorne ist für Klassen vorgesehen.
http://www.oracle.com/technetwork/java/codeconventions-135099.html

von Eric B. (beric)


Lesenswert?

JavaAnfänger schrieb:
> //Methode zum ändern des Fuellstandes
>     public static void tanken (int liter){
>       if(liter<=0 || fuellstand + liter > groesse){
>       }else{
>         fuellstand = fuellstand + liter;
>     }

Die methode tanken soll nicht static sein.
Warum ist der Parameter liter ein int und kein double? Kann ich kein 
23,41 liter tanken?

von Mike (Gast)


Lesenswert?

Die Tankroutine
1
  public static void tanken (int liter){
2
      if(liter<=0 || fuellstand + liter > groesse){
3
      }else{
4
        fuellstand = fuellstand + liter;
5
    }
sollte nicht static sein. Der Aufruf macht nur Sinn, wenn eine Instanz 
der Klasse existiert.

Ausserdem wird nichts in den Tank gefüllt, wenn die zu tankende Menge 
die Kapazität überschreitet. Ist das so gewollt? Sinnvoller wäre es, in 
diesem Fall den Tank komplett zu füllen

von JavaAnfänger (Gast)


Lesenswert?

1
import java.io.BufferedReader;
2
import java.io.IOException;
3
import java.io.InputStreamReader;
4
5
public class Autotank {
6
  private static double groesse;
7
  private static double fuellstand;
8
  private static double verbrauch;
9
10
  // Konstruktor mit drei Parametern für die Anfangswerte der Attribute
11
  public Autotank(double a, double b, double c) {
12
13
    groesse = a;
14
    fuellstand = b;
15
    verbrauch = c;
16
  }
17
18
  // Methoden: fuellstand, verbrauch, tanken, fahren, reichweite:
19
  public double GetFuellstand() {
20
    return fuellstand;
21
  }
22
23
  public double GetVerbrauch() {
24
    return verbrauch;
25
  }
26
27
  public static void tanken(double liter) {
28
    if (liter <= 0 ) {
29
    } else if (fuellstand + liter > groesse){
30
      fuellstand = groesse;
31
    }
32
    else { 
33
    
34
      fuellstand = fuellstand + liter;
35
    }
36
    
37
  }
38
39
  static void fahren (int Kilometerzahl) {
40
    fuellstand = fuellstand -((verbrauch*Kilometerzahl)/100);
41
    
42
  }
43
  static double Reichweite (double kilometer){
44
    kilometer = (fuellstand/verbrauch)*100;
45
    return kilometer;
46
  }
47
  
48
  public static void main(String args[]) throws IOException {
49
      
50
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
51
      int choice = 0;
52
      Autotank a1 = new Autotank(100, 50, 5);
53
      do {
54
        
55
        System.out.println();
56
        System.out.println("Bitte waehlen:");
57
        System.out.println("(1) Fuellstand abfragen");
58
        System.out.println("(2) Verbrauch abfragen");
59
        System.out.println("(3) Tanken");
60
        System.out.println("(4) Fahren");
61
        System.out.println("(5) Reichweite");
62
        System.out.println("(0) Ende");
63
        choice = Integer.parseInt(in.readLine());
64
        System.out.println();
65
        
66
        switch (choice) {
67
          
68
          case 1: System.out.println(a1.GetFuellstand());
69
70
          break;
71
          
72
          case 2: System.out.println(a1.GetVerbrauch());
73
74
          break;
75
          
76
          case 3: tanken(in.read());
77
78
          break; 
79
          
80
          case 4: fahren(in.read());
81
82
          break;
83
          
84
          case 5: System.out.println(Reichweite(fuellstand));
85
86
          break;
87
          
88
        }
89
        
90
      
91
        
92
      } while (choice!=0);
93
      
94
    }
95
    
96
  
97
98
  }
So sieht der Code jetzt aus.
Wenn ich tanken() nicht static ist, bemängelt mir das Eclipse im 
Hauptprogramm.

Wie muss ich z.b. den Methodenaufruf in der Switchcase anweisung genau 
schreiben bei tanken() und fahren()?
Wenn ich z.b. das Programm laufen lassen und 3 für tanken drücke und 
dann die Literanzahl eingebe, nimmt er immer nur den ersten Wert. Also 
2(0)<- Nimmt er garnicht). Er nimmt also quasi nur die 2. Ruft dann aber 
auch gleichzeitig wieder die Methode für 2 auf und bricht dann ab 
aufgrund der 0.

von Achim H. (anymouse)


Lesenswert?

Lieber JavaAnfänger (Gast),

Du solltest Dich einmal ausführlich mit dem Unterschied von 
Klassen-Methoden/Variablen/.. (static) und Instanz-Methoden/Variablen/.. 
(NICHT static) beschäftigen, und wie man diese aufruft

Beispiel: Autotank.tanken(double) vs. a1.tanken(double) ).

Du machst eine sehr seltsame Kombination, die vermutlich nicht Dein 
Wunsch ist. Daraus kommen auch so komische Effekte wie "Wenn ich 
tanken() nicht static ist, bemängelt mir das Eclipse im Hauptprogramm."

Danach kümmern wir uns mal um das mit den Bezeichnungen und den Fehlern.

von Mark B. (markbrandis)


Lesenswert?

Achim H. schrieb:
> Lieber JavaAnfänger (Gast),
>
> Du solltest Dich einmal ausführlich mit dem Unterschied von
> Klassen-Methoden/Variablen/.. (static) und Instanz-Methoden/Variablen/..
> (NICHT static) beschäftigen, und wie man diese aufruft

Dafür müsste man halt mal nachlesen, was es damit auf sich hat. Aber das 
ist ja uncool. Lieber einfach wild drauflos hacken... :-(

von JavaAnfänger (Gast)


Lesenswert?

Nochmal die Skripte angeguckt und werde mir nochmal alles genauer 
durchlesen und versuchen besser zu verstehen. Immerhin das mit static 
hab ich verstanden und auch warum in.read(); nicht klappt.
1
import java.io.BufferedReader;
2
import java.io.IOException;
3
import java.io.InputStreamReader;
4
5
public class Autotank {
6
  private double groesse;
7
  private double fuellstand;
8
  private double verbrauch;
9
10
  // Konstruktor mit drei Parametern für die Anfangswerte der Attribute
11
  public Autotank(double a, double b, double c) {
12
13
    groesse = a;
14
    fuellstand = b;
15
    verbrauch = c;
16
  }
17
18
  // Methoden: fuellstand, verbrauch, tanken, fahren, reichweite:
19
  public double GetFuellstand() {
20
    return fuellstand;
21
  }
22
23
  public double GetVerbrauch() {
24
    return verbrauch;
25
  }
26
27
  public void tanken(double liter) {
28
    if (liter <= 0 ) {
29
    } else if (fuellstand + liter > groesse){
30
      fuellstand = groesse;
31
    }
32
    else { 
33
    
34
      fuellstand = fuellstand + liter;
35
    }
36
    System.out.println("Getankt"+liter);
37
  }
38
39
  public boolean fahren (int Kilometerzahl) {
40
    fuellstand = fuellstand -((verbrauch*Kilometerzahl)/100);
41
    return true;
42
    
43
  }
44
  public double Reichweite (double kilometer){
45
    kilometer = (fuellstand/verbrauch)*100;
46
    return kilometer;
47
  }
48
  
49
  public static void main(String args[]) throws IOException {
50
      
51
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
52
      int choice = 0;
53
      boolean erfolg;
54
      Autotank a1 = new Autotank(80, 50, 7.5);
55
      
56
      do {
57
        
58
        System.out.println();
59
        System.out.println("Bitte waehlen:");
60
        System.out.println("(1) Fuellstand abfragen");
61
        System.out.println("(2) Verbrauch abfragen");
62
        System.out.println("(3) Tanken");
63
        System.out.println("(4) Fahren");
64
        System.out.println("(5) Reichweite");
65
        System.out.println("(0) Ende");
66
        choice = Integer.parseInt(in.readLine());
67
        System.out.println();
68
        
69
        switch (choice) {
70
          
71
          case 1: System.out.println(a1.GetFuellstand());
72
73
          break;
74
          
75
          case 2: System.out.println(a1.GetVerbrauch());
76
77
          break;
78
          
79
          case 3: a1.tanken(Double.parseDouble(in.readLine()));
80
              
81
82
          break; 
83
          
84
          case 4: a1.fahren(Integer.parseInt(in.readLine()));
85
86
          break;
87
          
88
          case 5: System.out.println(a1.Reichweite(a1.GetFuellstand()));
89
90
          break;
91
          
92
        }
93
        
94
      
95
        
96
      } while (choice!=0);
97
      
98
    }
99
    
100
  
101
102
  }

Die Methode fahren muss ich noch bearbeiten. Bitte die nicht 
berücksichtigen.

von Eric B. (beric)


Lesenswert?

Mike schrieb:
> Ausserdem wird nichts in den Tank gefüllt, wenn die zu tankende Menge
> die Kapazität überschreitet. Ist das so gewollt? Sinnvoller wäre es, in
> diesem Fall den Tank komplett zu füllen

...und ein Overflow-Exception zu schmeissen :-)

von JavaAnfänger (Gast)


Lesenswert?

JavaAnfänger schrieb:
> public void tanken(double liter) {
>     if (liter <= 0 ) {
>     } else if (fuellstand + liter > groesse){
>       fuellstand = groesse;
>     }
>     else {
>
>       fuellstand = fuellstand + liter;

Eric B. schrieb:
> Mike schrieb:
>> Ausserdem wird nichts in den Tank gefüllt, wenn die zu tankende Menge
>> die Kapazität überschreitet. Ist das so gewollt? Sinnvoller wäre es, in
>> diesem Fall den Tank komplett zu füllen
>
> ...und ein Overflow-Exception zu schmeissen :-)


Die Methode macht folgendes:
Wenn eine negativezahl getankt wird, passiert nichts.
Wenn übertankt wird, dann wird der tank nur bis max der Tankgröße 
befüllt.
Ansonsten wird der Fuellstand des tankes mit den getankten Litern 
addiert.

von Mladen G. (Gast)


Lesenswert?

1
 public Autotank(double a, double b, double c) {
2
3
    groesse = a;
4
    fuellstand = b;
5
    verbrauch = c;
6
  }
.. umgekehrt wird ein Schuh draus, deklariere die Parameter des 
Konstruktors als final und der Compiler wird dir helfen ;)

von cppler (Gast)


Lesenswert?

Sauber OO programmieren bedeutet auch OO verstanden zu haben.
Üblicherweise werden interne Variablen eines Objekts auch nur intern 
verwendet.
Stichwort "getter" und "setter" das hast Du ja halb umgesetzt.
Dann gibt es noch die Vererbung und ein Tank ist wie schon gesagt kein 
Motor geschweige denn ein Auto o.ä.
Also gehe systematisch vor und beschreibe jedes Objekt Deines Autos 
einzeln, dann bekommst Du Klassen wie Motor, Tank, Tür usw. usf.
Daraus kannst Du dann was machen.
Achja und Destruktoren sind auch immer was feines ...

von Mark B. (markbrandis)


Lesenswert?

cppler schrieb:
> Sauber OO programmieren bedeutet auch OO verstanden zu haben.
> Üblicherweise werden interne Variablen eines Objekts auch nur intern
> verwendet.
> Stichwort "getter" und "setter" das hast Du ja halb umgesetzt.

...und wenn man es ganz ganz ganz ganz richtig macht, dann kann man auf 
Getter und Setter oftmals verzichten. Wenn man diese permanent und für 
alles benutzt, hat man eines ganz sicher nicht: Ein richtig gutes 
objektorientiertes Software-Design.

OOP bedeutet unter anderem, dass Objekte zur Laufzeit über Nachrichten 
miteinander kommunizieren. So wie es z.B. in Smalltalk üblich ist. Diese 
Nachrichten sollten aber nicht ständig trivial sein à la "gib mir Wert 
X, und ich rechne dann mit diesem".

Siehe zum Beispiel:
Why getter and setter methods are evil
http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html
Doing it wrong: getters and setters
http://typicalprogrammer.com/doing-it-wrong-getters-and-setters/

> Achja und Destruktoren sind auch immer was feines ...

Nicht in Java, weil das dort der Garbage Collector übernimmt.

: Bearbeitet durch User
Beitrag #6384398 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.