Übernommene Variablen(werte) aus der Main-Klasse ändern?

Berlin_er

Mitglied
Guten Tag zsm!

Ich bin gerade bei der Objektorientierung (Klasse,Attribute,Methoden..) dran und habe folgendes Problem:

Ich weiß bereits wie ich Variablen + V.-werte aus der Main-Klasse in eine andere Klasse übernehme. Ich kann es auch z.b. für Ausgaben benutzen. Jedoch verstehe ich noch nicht ganz, wie ich übernommene Variablen(Werte) aus der Main-Klasse in der anderen Klasse ändern kann. In den folgenden Codes habe ich die Variable richter, Typ boolean übernommen. In Methoden kann ich es benutzen, jedoch nicht ändern. In dem Fall von true auf false.

Edit: Geändert werden soll die Variable richter von true auf false in der Methode "ausgabe".

Meine Main-Klasse:
Code:
public class Start{
  public static void main(String [] args){
 
    boolean richter = false;
 
    Quader meinQuader;
    Kugel meineKugel;
    Zylinder meinZylinder;
 
    while (richter == false) {
 
      String produktart = InOut.readString("Produktart? ");
 
      if (produktart.equalsIgnoreCase("Quader")) {
        meinQuader = new Quader();
        meinQuader.abfrage();
        meinQuader.berechnung();
        meinQuader.ausgabe();
        richter = true;
      }
      else if (produktart.equalsIgnoreCase("Kugel")){
        meineKugel = new Kugel();
        meineKugel.kugelDatenEingabe();
        meineKugel.kugelBerechnung();
        meineKugel.kugelDatenAusgabe();
        richter = true;
      }
      else if (produktart.equalsIgnoreCase("Zylinder")) {
        meinZylinder = new Zylinder(richter);
        meinZylinder.abfrage();
        meinZylinder.berechnung();
        richter = true;
        meinZylinder.ausgabe();
      }
      else
      System.out.println("Ein Fehler ist aufgetreten!");
    }
  }
}

die andere Klasse:
Code:
import java.text.DecimalFormat;
public class Zylinder{
  // Anfang Attribute
  private double zylinderpreis;
  private double zylindervolumen;
  private double radius;
  private double hoehe;
  boolean richter;
  DecimalFormat a = new DecimalFormat("#0.00");
  // Ende Attribute
 
  public Zylinder(boolean prichter) {
    richter = prichter;
  }
 
  // Anfang Methoden
  public void abfrage() {
    radius = InOut.readDouble("Radius? ");
    hoehe = InOut.readDouble("Höhe? ");
  }
 
  public void berechnung() {
    zylindervolumen = Math.PI * Math.pow(radius,2) * hoehe;
 
    if (zylindervolumen > 3 && zylindervolumen < 3000)
    zylinderpreis = 0.002 * zylindervolumen + 0.25;
  }
 
  public void ausgabe() {
    if (zylindervolumen > 3 && zylindervolumen < 3000)
    System.out.println("\nVolumen beträgt: "+a.format(zylindervolumen)+" ccm\nPreis beträgt: "+a.format(zylinderpreis)+" Euro");
    else {
      richter = false;
      System.out.println("Das Volumen liegt nicht zwischen 3 ccm und 3000 ccm!");
    }
  }
  // Ende Methoden
}
 
Zuletzt bearbeitet:
Java hat die "Call by Value" Aufrufsemantik für Methoden (und Konstruktoren), bei der Kopien von aktuellen Argumenten für Methodenaufrufe angelegt werden und die Methode wird mit diesen Kopien aufgerufen. Du kannst also keine Variablen innerhalb des Methodenaufrufes nach außen sichtbar verändern, weil die Methode selbst immer nur auf Kopien der Werte arbeitet. Letztlich gibst du einem Methodenaufruf ja auch immer einen "Ausdruck" als Argumentwert. Dass dieser Ausdruck auch eine Variable sein kann heißt nicht, dass damit die Variable an sich gemeint ist. Es ist immer nur der Wert entscheidend, den der Ausdruck generiert. Und eine Variable generiert den Wert, den diese Variable zum Zeitpunkt des Aufrufes gespeichert hat.
Siehe auch: https://javabeginners.de/Grundlagen/Call_by_Value.php
 
@Berlin_er
Java:
public class Door
{

    final static int DOOR_POSITION = 100;

    public boolean isClose(double value)
    {
        return value == DOOR_POSITION;
    }
}

public class IchBinEinBerliner
{
    public static void main(String[] args)
    {
        double closed = 100;
        Door door = new Door();
        boolean doorIsClosed = door.isClose(closed);
        String info = doorIsClosed ? "Door is closed" : "Door is open";
        System.out.println(info);
    }
}
/** Output */
Door is closed
Ich hätte die Abfragen nicht in der Klasse durchgeführt. Eine Klasse Zylinder hat radius und hoehe als Konstruktorparameter zu bekommen. Anhand dieser soll, vorausgesetzt die Prüfung der beiden Parameter gegen Null positiv verlief, automatisch passieren, so dass volume gleich zu Verfügung steht.
Ebenso würde ich die Infos in der Main-Methode abwickeln. Zudem hast du Doppelcode hier und da
Java:
if (zylindervolumen > 3 && zylindervolumen < 3000)
Lagere es in eine private Methode der Klasse aus und greif dann ggf. zu.
Die Werte 3, 3000, 0.002 und 0.25 hätte ich als finale Variablen deklariert. Hat den Vorteil, dass es nur an einer Stelle zu ändern ist, falls es geändert werden muss.
Java:
 (richter == false)
boolean x = true;
if(x) {...} else {x = !x} ! - Negation wenn die else-Abfrage kommen sollte, wird x negiert und ist ab da false 😉
 
Du kannst also keine Variablen innerhalb des Methodenaufrufes nach außen sichtbar verändern, weil die Methode selbst immer nur auf Kopien der Werte arbeitet. Letztlich gibst du einem Methodenaufruf ja auch immer einen "Ausdruck" als Argumentwert.
Das stimmt so nicht ganz. Wenn als Parameter ein mutable Objekt übergeben wird, kann innerhalb der Methode das Objekt verändert werden. Das stellt ein Problem der Sprache Java dar, bezüglich Sicherheit innerhalb eines Objektes.
In C++ kann man Parameter und die Funktion als const deklarieren , um so etwas zu verhindern. In Java muss man finale Klassen als Parameter benutzen, da sich final als Parameter nur auf die Referenz des Objektes nicht aber auf dessen Attribute bezieht. ( siehe Code )
Code:
public class TestParam {
    private String name = "original";
    public void setName(final String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return name;
    }
}
Code:
public static void testCall( final TestParam p) {
        p.setName("geändert");
    }
Code:
TestParam test = new TestParam();
        System.out.println("vorher: \t" + test);
        testCall(test);
        System.out.println("nachher:\t" + test);
Ergebnis:
vorher: original
nachher: geändert

😉
 
Zuletzt bearbeitet:
Es stimmt trotzdem. Du kannst trotzdem niemals die Variable, die auf ein Objekt zeigt, auf ein anderes Objekt zeigen lassen. Also: Du kannst niemals die ursprüngliche Variable in ihrem Inhalt verändern.
Dass du natürlich ein Feld innerhalb des Objektes ändern kannst, das der Wert der Variablen war, ist davon unberührt.
 
Das stimmt so nicht ganz. Wenn als Parameter ein mutable Objekt übergeben wird, kann innerhalb der Methode das Objekt verändert werden. Das stellt ein Problem der Sprache Java dar, bezüglich Sicherheit innerhalb eines Objektes.
In C++ kann man Parameter als const deklarieren , um so etwas zu verhindern. In Java muss man finale Klassen als Parameter benutzen, da sich final als Parameter nur auf die Referenz des Objektes nicht aber auf dessen Attribute bezieht.
Naja, das stellt nur ein Problem deines Designs da, wenn das Objekt Änderungen zulässt, dann ist das eben so 😉
Allerdings ist generell nichts in Java wirklich immutable, mit Reflection geht alles...

BTW muss nicht die Klasse final sein (das verhindert nur Vererbung), sondern die Klasse sollte einfach von außen unveränderlich sein 😉
 

Neue Themen


Zurück
Oben