# Umrechnung von Einheiten



## Degget (27. Nov 2009)

Hallo. Ich sitze gerade bei einer Aufgabe für die Uni. Das Ziel ist, nach der Eingabe eines Radius den Durchmesser, Oberfläche und Volumen einer Kugel ausgegeben zu bekommen. Dies soll allerdings in jeweils 8 unterschiedlichen Einheiten passieren. Ich weiß nicht, wie ich dieses Problem am besten angehen soll. Bisher habe ich eine Mainclass (die Ausgabe stimmt noch nicht, weil ich das Einheitenproblem nicht lösen konnte) und eine Klasse zur Berechnung der Werte. Wie mach ich jetzt am besten weiter?


```
import java.io.IOException;
public class KugelMain
{
  public static void main (String[] args) throws IOException
  {
    Kugel kugel = new Kugel();
    System.out.print("Programm zur Berechnung von Kugelgroessen.\n");
	System.out.print("Bitte Radius in cm eingeben: ");
	kugel.erfasseRadius(MeineEingabe.erfasseDouble());
	System.out.printf("%.2f %.2f %.2f", kugel.Radius(), kugel.Durchmesser(), kugel.Oberflaeche());
   }
}
```


```
import java.lang.Math;

public class Kugel
{
  private double radius;
  private double durchmesser;
  private double umfang;
  private double oberflaeche;
  private double volumen;
  
  public void erfasseRadius(double radius) 
  {
    this.radius = radius;
  }
  public double Durchmesser() 
  {
    durchmesser = radius * 2.0;
    return durchmesser;
  }
  public double Umfang() 
  {
    umfang = 2 * Math.PI * radius;
	return umfang;
  }
  public double Oberflaeche() 
  {
    oberflaeche = 4 * Math.PI * radius * radius; 
    return oberflaeche;
  }
  public double Volumen() 
  {
    volumen = 4 / 3 * Math.PI * radius * radius * radius;
	return volumen;
  }
  public double Radius()
  {
    return radius;
  }
}
```

Ich dachte daran, nun eine separate Klasse für die Umrechnung in verschiedene Einheiten zu stellen. Allerdings weiß ich nicht, wie man das effektiv macht. Für jeden Wert und jede Einheit eine Methode schreiben wäre wohl sinnlos, oder? (Man käme immerhin auf 48 Methoden...)


----------



## javimka (28. Nov 2009)

Was sind denn das für einheiten? Wenne es mm, cm, dm, m, km o.ä sind, kannst du die ja ganz einfach mit /100, *100 oder was auch immer umrechnen. Oder sind es Einheiten wie Meilen oder Lichtjahre? Dann Könntest du eine Klasse schreiben, deren Konstruktor einen Wert in Meter übernimmt und Methoden wie getInMiles(), getInLightyears() usw. anbietet, die dann die Umrechnung von Meter in die entsprechende Einheit übernehmen.

Methoden schreibt man in Java übrigens immer klein, also besser wäre [c]umfang()[/c] statt [c]Umgang()[/c] und noch besser wäre etwas wie getUmfang() oder compute/create/calculateUmfang().


----------



## Spacerat (28. Nov 2009)

Ich hatte diese Problematik mal bei berechnung von Winkeln. Als es mir zu viele Methoden wurden, hab' ich mir so eine Enumeration gebastelt.
	
	
	
	





```
public enum AngleType
{
	DEG(180.0f / (float) Math.PI, 360.f),
	RAD(1.0f, (float) Math.PI * 2.0f), // standard
	GRAD(200.0f / (float) Math.PI, 400.0f),
	;

	public final float factor, maxvalue;

	private AngleType(float factor, float maxvalue)
	{
		this.factor = factor;
		this.maxvalue = maxvalue;
	}
}
```
Wenn man z.B. in DEG rechnen wollte, musste man diese Einheit mit übergeben. Intern wurde ausschliesslich mit RAD gerechnet.


----------



## Degget (28. Nov 2009)

Den unteren Code versteh ich leider nicht so richtig. Was ist ein enum? Eine spezielle class? 
Ich hab jetzt erstmal die Methodennamen geändert und die Umrechnung direkt in die Ausgabe der Main gepackt:

```
import java.io.IOException;
public class KugelMain
{
  public static void main (String[] args) throws IOException
  {
    Kugel kugel = new Kugel();
    System.out.print("Programm zur Berechnung von Kugelgroessen.\n");
	System.out.print("Bitte Radius eingeben: ");
	kugel.setRadius(MeineEingabe.erfasseDouble());
	System.out.printf("%17s %13s %11s \n", "Radius", "Durchmesser", "Umfang");
	System.out.printf("Millimeter %.2f %10.2f %15.2f \n", kugel.getRadius() * 10, kugel.calculateDurchmesser() *10, kugel.calculateUmfang() *10);
	System.out.printf("Zentimeter %.2f %10.2f %15.2f \n", kugel.getRadius(), kugel.calculateDurchmesser(), kugel.calculateUmfang());
	System.out.printf("Meter      %.2f %10.2f %15.2f \n", kugel.getRadius() / 100, kugel.calculateDurchmesser() / 100, kugel.calculateUmfang() / 100);
	System.out.printf("Kilometer  %.5f %10.5f %15.5f \n", kugel.getRadius() / 100000, kugel.calculateDurchmesser() / 100000, kugel.calculateUmfang() / 100000);
   }
}
```

Ich find das allerdings recht unübersichtlich und es genügt glaube ich auch nicht den Anforderungen der Aufgabenstellung. Also muss es wohl durch Methoden erledigt werden. Wie genau mache ich sowas? Die berechneten Werte sind ja erstmal in cm, cm² oder cm³. Will jetzt eine Methode wie zB

```
public double getInMeters()
{
 wert/100 = meters;
 return meters;
}
```

Wie mache ich es, dass er den jeweiligen Wert aus den Methoden Radius, Durchmesser, Umfang, Oberfläche und Volumen nimmt ohne dass ich für jedes eine neue Methode schreibe?


----------



## javimka (28. Nov 2009)

du könntest eine statische Methode schreiben von der Art:

```
private static double cmToM(double cm) {
   return cm/100;
}
```
Und um dann den Durchmesser in Meter auszudrücken: cmToM(kugel.getDurchmesser())


----------



## Spacerat (28. Nov 2009)

...Wie es oben schon steht: *enum* = Enumeration. Eine Aufzählung, sozusagen. Dieses Schlüsselwort ist ab JRE1.5 vorhanden und erzeugt konstante Instanzen einer Klasse (In meinem Beispiel AngleType). Angenommen wir hätten eine Klasse, die irgendwo einen Winkel im Bogenmaß (RAD) speichert und wir diesen Wert in anderen Einheiten haben bzw. zurückgeben wollen. Normalerweise müsste man für jede Einheit, die wir zurückgeben wollen, eine separate Methode implementieren (so wie du dir das vorstellst). Mit einer solchen Enumeration reicht dagegen eine!
	
	
	
	





```
class AngleStoringClass
{
  private float angle;

  public void set(float angle)
  {
    set(angle, AngleType.RAD);
  }

  public void set(float angle, AngleType unit)
  {
    if(unit == null) {
      unit = AngleType.RAD;
    }
    this.angle = angle / unit.factor;
    this.angle %= unit.maxvalue;
  }

  public float get()
  {
    return angle;
  }

  public float getAs(AngleType unit)
  {
    if(unit == null) {
      unit = AngleType.RAD;
    }
    return (angle * unit.factor) % unit.maxvalue;
  }
}
```
Ok... sind doch zwei geworden... Aber bitte um Nachsicht... Eine davon ist die standard-get-Methode


----------



## Degget (29. Nov 2009)

Schon mal Danke bis hierhin. Hat mir wirklich weitergeholfen. Ich werde auf jeden Fall mal beide Wege ausprobieren. Eine Frage habe ich allerdings noch: Wieso sollte ich die "private static double cmToM(double cm)"-Methode private machen? Wäre public nicht besser, weil ich dann von anderen Klassen auf sie zugreifen könnte?


----------



## javimka (29. Nov 2009)

Wenn du von anderen Klassen darauf zugreifen willst, dann ist public oder protected sinnvoll. Aber sonst gilt die Regeln, dass die Attribute und Methoden so private wie möglich sein sollten.


----------

