Wie benutze ich richtig "this"?

kingpin000

Mitglied
Hallo,
ich hab in meinem aktuellen Uni-Programm das Problem, dass ich die Klassenvariablen durch die this-Anweisung verheize und er mir nach der ersten Benutzung der Klasse nur noch Murks anzeigt.
Ich seh den Wald vor lauter Fehlern nicht mehr....

Die Klasse
Java:
	@SuppressWarnings("serial")
	class DivideByZeroException extends Exception
	{
		public DivideByZeroException() {}    
		public DivideByZeroException(String s)
		{
			super(s);
		}
	}

public class Complex
{
	
	private double realTeil = 0.0;  
	private double imagTeil = 0.0;

    public Complex(double r, double i)
    {
    	realTeil = r;  
        imagTeil = i;
    }
	   	
	double getRealTeil()
	{
		return this.realTeil;
	}
	
	double getImagTeil()
	{
		return this.imagTeil;
	}
	
	void set(double r, double i)
	{
		this.realTeil = r;
		this.imagTeil = i;
	}
	
	void add(Complex z)
	{
		this.realTeil = this.realTeil + z.realTeil;
		this.imagTeil = this.imagTeil + z.imagTeil;
	}
	
	public Complex plus(Complex z2)
	{
		this.add(z2);
		return this;
	}
	
	void subtract(Complex z)
	{
		this.realTeil = this.realTeil - z.realTeil;
		this.imagTeil = this.imagTeil - z.imagTeil;
	}
	
	public Complex minus(Complex z2)
	{
		this.subtract(z2);
		return this;
	}
	void multiplyBy(Complex z)
	{	
		this.realTeil = (this.realTeil * z.realTeil) - (this.imagTeil * z.imagTeil);
		this.imagTeil = (this.realTeil * z.imagTeil) + (this.imagTeil * z.realTeil);
	}
	
	public Complex multipliedBy(Complex z2)
	{
		this.multiplyBy(z2);
		return this;	
	}
	
	void divideBy(Complex z) throws DivideByZeroException
	{
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;
		double div = ((r2*r2)+(i2*i2));
		
		if (div == 0.0)
		{
			throw new DivideByZeroException("0 ist als Divisor nicht definiert");
		}
		else
			{
			r1 = ((r1 * r2) + (i1 * i2))/(div);
			i1 = ((r1 * i2) - (i1 * r2))/(div);
			}
	}
	
	public Complex dividedBy(Complex z2) throws DivideByZeroException
	{
		this.divideBy(z2);
		return this;
	}
	
	public double betrag()
	{
		double r = this.realTeil;
		double i = this.imagTeil;
		
		return Math.sqrt((r*r) + (i*i));
	}
	
	public boolean equals(Complex z)
	{
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;
		
		if (r1 == r2 && i1 == i2)
			return true;
		return false;
	}
	
    public String toString() 
    {
        if (imagTeil == 0)
        {
        	return realTeil + "";
        }
        else if (realTeil == 0)
        	{
        		return imagTeil + "i";
        	}
        else if (imagTeil <  0)
        		{
        			return realTeil + " - " + (-imagTeil) + "i";
        		}
        		else
        			{
        				return realTeil + " + " + imagTeil + "i";
        			}
    }

}


Das Testprogramm
Java:
public class ComplexText {
    public static void main(String[] args) 
    {
    	try
    	{
        Complex z1 = new Complex(5.0, 6.0);
        Complex z2 = new Complex(3.0, 2.0);

        System.out.println("z1 = " + z1);
        System.out.println("z2 = " + z2);            
        System.out.println("z1 + z2 = " + z1.plus(z2));
        System.out.println("z1 - z2 = " + z1.minus(z2));
        System.out.println("z1 * z2 = " + z1.multipliedBy(z2));
        System.out.println("z1 / z2 = " + z1.dividedBy(z2)); 
        System.out.println("|z1| = " + z1.betrag());
        System.out.println("|z2| = " + z2.betrag());
        System.out.println("z1 = z2? " + z1.equals(z2));
    	}
		catch (DivideByZeroException exc)
		{
			System.out.println( exc.getMessage());
		} 
    }

}
 
am besten immer dann, wenn du auf Member innerhalb der Klasse zugreifst, so sieht gleich jeder, der den Quelltext liest, wo er die Deklaration zu suchen hat. Erforderlich wird's, wenn z.B. dein Konstruktor von Complex etwa so aussieht:
Java:
class Complex {
  private double realTeil, imagTeil;

  Complex(double realTeil, double imagTeil) {
    this.realTeil = realTeil;
    this.imagTeil = imagTeil;
  }
}
Murks kommt bei dir anscheinend bei der Methode "multiplyBy()" heraus, weil du die Ausgangswerte von this nicht zwischenspeicherst und deswegen in deiner 2. Rechnung mit einem bereits verändertem "this.realTeil" weiter rechnest.
 
Zuletzt bearbeitet von einem Moderator:
Ich hab jetzt mal die Klasse abgeändert und bin über die Ergebnisse noch verwirrter...

Java:
	@SuppressWarnings("serial")
	class DivideByZeroException extends Exception
	{
		public DivideByZeroException() {}    
		public DivideByZeroException(String s)
		{
			super(s);
		}
	}

class Complex 
{
	private double realTeil, imagTeil;
		 
    Complex(double realTeil, double imagTeil)
    {
		this.realTeil = realTeil;
		this.imagTeil = imagTeil;
    }
		
	   	
	double getRealTeil()
	{
		return this.realTeil;
	}
	
	double getImagTeil()
	{
		return this.imagTeil;
	}
	
	void set(double r, double i)
	{
		this.realTeil = r;
		this.imagTeil = i;
	}
	
	void add(Complex z)
	{
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;
		
		r1 = r1 + r2;
		i1 = i1 + i2;
	}
	
	public Complex plus(Complex z2)
	{
		Complex z1 = new Complex(realTeil, imagTeil);
		z1 = this;
		z1.add(z2);
		return z1;
	}
	
	void subtract(Complex z)
	{
		this.realTeil = this.realTeil - z.realTeil;
		this.imagTeil = this.imagTeil - z.imagTeil;
	}
	
	public Complex minus(Complex z2)
	{
		Complex z1 = new Complex(realTeil, imagTeil);
		z1 = this;
		z1.subtract(z2);
		return z1;
	}
	void multiplyBy(Complex z)
	{	
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;
		
		r1 = (r1 * r2) - (i1 *i2);
		i1 = (r1 * i2) + (i1 * r2);
	}
	
	public Complex multipliedBy(Complex z2)
	{
		Complex z1 = new Complex(realTeil, imagTeil);
		z1 = this;
		z1.multiplyBy(z2);
		return z1;	
	}
	
	void divideBy(Complex z) throws DivideByZeroException
	{
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;
		double div = ((r2*r2)+(i2*i2));
		
		if (div == 0.0)
		{
			throw new DivideByZeroException("0 ist als Divisor nicht definiert");
		}
		else
			{
			r1 = ((r1 * r2) + (i1 * i2))/(div);
			i1 = ((r1 * i2) - (i1 * r2))/(div);
			}
	}
	
	public Complex dividedBy(Complex z2) throws DivideByZeroException
	{
		Complex z1 = new Complex(realTeil, imagTeil);
		z1 = this;
		z1.divideBy(z2);
		return z1;
	}
	
	public double betrag()
	{
		double r = this.realTeil;
		double i = this.imagTeil;
		
		return Math.sqrt((r*r) + (i*i));
	}
	
	public boolean equals(Complex z)
	{
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;
		
		if (r1 == r2 && i1 == i2)
			return true;
		return false;
	}
	
    public String toString() 
    {
        if (imagTeil == 0)
        {
        	return realTeil + "";
        }
        else if (realTeil == 0)
        	{
        		return imagTeil + "i";
        	}
        else if (imagTeil <  0)
        		{
        			return realTeil + " - " + (-imagTeil) + "i";
        		}
        		else
        			{
        				return realTeil + " + " + imagTeil + "i";
        			}
    }

}
 
add soll vermutlich die Werte der anderen Zahl auf die aktuelle addieren.
Aktuell setzt du in der Methode nur 2 Variablen die das Ergebnis beeinhalten, mit denen machst du aber nichts - nach dem Aufruf von add ist alles wie vorher.

was genau soll plus machen? sowas wie addieren und das ergebnis als neue zahl zurückgeben?

subtract sieht brauchbar aus, so ähnlich könnte man wohl auch add machen.

minus: gleiche frage wie bei plus

multiplyBy: gleiches Problem wie bei add

multipliedBy: gleiche frage wie bei plus

usw.

Gruß
 
add soll vermutlich die Werte der anderen Zahl auf die aktuelle addieren.
Aktuell setzt du in der Methode nur 2 Variablen die das Ergebnis beeinhalten, mit denen machst du aber nichts - nach dem Aufruf von add ist alles wie vorher.

was genau soll plus machen? sowas wie addieren und das ergebnis als neue zahl zurückgeben?

subtract sieht brauchbar aus, so ähnlich könnte man wohl auch add machen.

minus: gleiche frage wie bei plus

multiplyBy: gleiches Problem wie bei add

multipliedBy: gleiche frage wie bei plus

usw.

Gruß

Die Annahmen sind alle richtig.

Ich hab wieder alles entsprechend abgeändert, aber es besteht immer noch das Anfangsproblem.
Java:
	@SuppressWarnings("serial")
	class DivideByZeroException extends Exception
	{
		public DivideByZeroException() {}    
		public DivideByZeroException(String s)
		{
			super(s);
		}
	}

class Complex 
{
	private double realTeil, imagTeil;
		 
    Complex(double realTeil, double imagTeil)
    {
		this.realTeil = realTeil;
		this.imagTeil = imagTeil;
    }
		
	   	
	double getRealTeil()
	{
		return this.realTeil;
	}
	
	double getImagTeil()
	{
		return this.imagTeil;
	}
	
	void set(double r, double i)
	{
		this.realTeil = r;
		this.imagTeil = i;
	}
	
	void add(Complex z)
	{		
		this.realTeil = this.realTeil + z.realTeil;
		this.imagTeil = this.imagTeil + z.imagTeil;
	}
	
	public Complex plus(Complex z2)
	{
		Complex z1 = this;
		z1.add(z2);
		return z1;
	}
	
	void subtract(Complex z)
	{
		this.realTeil = this.realTeil - z.realTeil;
		this.imagTeil = this.imagTeil - z.imagTeil;
	}
	
	public Complex minus(Complex z2)
	{
		Complex z1 = this;
		z1.subtract(z2);
		return z1;
	}
	void multiplyBy(Complex z)
	{			
		this.realTeil = (this.realTeil * z.realTeil) - (this.imagTeil *z.imagTeil);
		this.imagTeil = (this.realTeil * z.imagTeil) + (this.imagTeil * z.realTeil);
	}
	
	public Complex multipliedBy(Complex z2)
	{
		Complex z1 = this;
		z1.multiplyBy(z2);
		return z1;	
	}
	
	void divideBy(Complex z) throws DivideByZeroException
	{
		double div = ((z.realTeil*z.realTeil)+(z.imagTeil*z.imagTeil));
		
		if (div == 0.0)
		{
			throw new DivideByZeroException("0 ist als Divisor nicht definiert");
		}
		else
			{
			this.realTeil = ((this.realTeil * z.realTeil) + (this.imagTeil * z.imagTeil))/(div);
			this.imagTeil = ((this.realTeil * z.imagTeil) - (this.imagTeil * z.realTeil))/(div);
			}
	}
	
	public Complex dividedBy(Complex z2) throws DivideByZeroException
	{
		Complex z1 = this;
		z1.divideBy(z2);
		return z1;
	}
	
	public double betrag()
	{
		double r = this.realTeil;
		double i = this.imagTeil;
		
		return Math.sqrt((r*r) + (i*i));
	}
	
	public boolean equals(Complex z)
	{
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;
		
		if (r1 == r2 && i1 == i2)
			return true;
		return false;
	}
	
    public String toString() 
    {
        if (imagTeil == 0)
        {
        	return realTeil + "";
        }
        else if (realTeil == 0)
        	{
        		return imagTeil + "i";
        	}
        else if (imagTeil <  0)
        		{
        			return realTeil + " - " + (-imagTeil) + "i";
        		}
        		else
        			{
        				return realTeil + " + " + imagTeil + "i";
        			}
    }

}
 
Ich nehme mal an, dass du unerwartete Werte ausgegeben bekommst oder?

Ein Problemkandidat sind diese Methoden:
Java:
 public Complex plus(Complex z2)
    {
        Complex z1 = this;
        z1.add(z2);
        return z1;
    }

mit der Zuweisung z1 = this erstellst du (bildlich) einen neuen Parkplatz, aber auf den Parkplatz stellst du das gleiche Auto.
Jetzt steckst du 3 Leute in das Auto (z1.add(z2)) und gibst das Auto an deinen Kollegen (return z1).

Machst du jetzt bei dem nächsten Aufruf weiter hast du allerdings immer noch das gleiche Auto, inklusive der 3 Kollegen die noch auf der Rückbank warten.

Was du vermutlich machen willst ist ein 2. Auto auf den 2. Parkplatz stellen, in das 2. Auto die gleichen Biervorräte packen die du aktuell auch im Kofferraum hast und dann deinen Kollegen mit dem anderen Auto wegfahren lassen 🙂 Dann kannst du nämlich zurück zu deinem Auto mit dem vollen Kofferraum und der leeren Rückbank gehen.

(neues Objekt erzeugen und die Werte des aktuellen Objekts übertragen, anschließend das neue Objekt zurückgeben 😉 )

Gruß
 
Ich nehme mal an, dass du unerwartete Werte ausgegeben bekommst oder?

Ein Problemkandidat sind diese Methoden:
Java:
 public Complex plus(Complex z2)
    {
        Complex z1 = this;
        z1.add(z2);
        return z1;
    }

mit der Zuweisung z1 = this erstellst du (bildlich) einen neuen Parkplatz, aber auf den Parkplatz stellst du das gleiche Auto.
Jetzt steckst du 3 Leute in das Auto (z1.add(z2)) und gibst das Auto an deinen Kollegen (return z1).

Machst du jetzt bei dem nächsten Aufruf weiter hast du allerdings immer noch das gleiche Auto, inklusive der 3 Kollegen die noch auf der Rückbank warten.

Was du vermutlich machen willst ist ein 2. Auto auf den 2. Parkplatz stellen, in das 2. Auto die gleichen Biervorräte packen die du aktuell auch im Kofferraum hast und dann deinen Kollegen mit dem anderen Auto wegfahren lassen 🙂 Dann kannst du nämlich zurück zu deinem Auto mit dem vollen Kofferraum und der leeren Rückbank gehen.

(neues Objekt erzeugen und die Werte des aktuellen Objekts übertragen, anschließend das neue Objekt zurückgeben 😉 )

Gruß
Ich bekomm entweder nur Z1 oder unsinnige Rechenergebnisse wieder.

Gutes Beispiel, damit verstehe ich zwar gedanklich, aber das jetzt in Code umzuwandeln ist eine andere Sache.
Ich hab mich mal an dem Code von dieser Seite hier orientiert, aber das klappt immer noch nicht.
Java:
	public Complex plus(Complex z2)
	{
		Complex z1 = this;
		z1.add(z2);
		return new Complex(realTeil, imagTeil);
	}
 
Problemkandidaten sind solche Geschichten hier... (das hatte ich schon weiter oben erwähnt...
Java:
        this.realTeil = (this.realTeil * z.realTeil) - (this.imagTeil * z.imagTeil);
        this.imagTeil = (this.realTeil * z.imagTeil) + (this.imagTeil * z.realTeil);
In der 2. Zeile wird das bereits veränderte "this.realTeil" zur weiteren Berechnung verwendet.
Mach sowas draus:
Java:
double rt = this.realTeil;
double it = this.imagTeil:

this.realTeil = (rt * z.realTeil) - (it * z.imagTeil);
this.imaGTeil = (rt * z.imagTeil) + (it * z.realTeil);

Darüber hinaus, würde ich auch die Stellen noch mal überprüfen, an denen du das bereits ähnlich machst (bzw. anfangs gemacht hast).
Der Ablauf ist immer der selbe:
1. this-Variablen zwischenspeichern
2. Berechnungen mit Zwischenspeichern durchführen und Ergebnisse den this-Variablen zuweisen.

3. Wenn man während den Berechnungen aber die Zwischenspeicher ändert, wird das Ergebnis gerade wie zuvor auch verfälscht.
[EDIT]Ansonsten ist so etwas
Java:
public void add(Complex z) {
  // your code
}

public Complex plus(Complex z) {
/*  Complex t = this;
    t.add(z);
    return t; */
  add(z);
  return this;
}
vollkommen okay und ausreichend (vorrausgesetzt "add()" verändert "this").[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
Was looooos? Kannsu nix läsn? :lol:
Java:
public class Complex {
	private double realTeil, imagTeil;

	Complex(double realTeil, double imagTeil) {
		this.realTeil = realTeil;
		this.imagTeil = imagTeil;
	}

	double getRealTeil() {
		return realTeil;
	}

	double getImagTeil() {
		return imagTeil;
	}

	void set(double realTeil, double imagTeil) {
		this.realTeil = realTeil;
		this.imagTeil = imagTeil;
	}

	void add(Complex z) {
		this.realTeil = this.realTeil + z.realTeil;
		this.imagTeil = this.imagTeil + z.imagTeil;
	}

	public Complex plus(Complex z2) {
		add(z2);
		return this;
	}

	void subtract(Complex z) {
		this.realTeil = this.realTeil - z.realTeil;
		this.imagTeil = this.imagTeil - z.imagTeil;
	}

	public Complex minus(Complex z2) {
		subtract(z2);
		return this;
	}

	void multiply(Complex z) {
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;

		this.realTeil = (r1 * r2) - (i1 * i2);
		this.imagTeil = (r1 * i2) + (i1 * r2);
	}

	public Complex multiplyWith(Complex z2) {
		multiply(z2);
		return this;
	}

	void divide(Complex z) {
		double r1 = this.realTeil;
		double r2 = z.realTeil;
		double i1 = this.imagTeil;
		double i2 = z.imagTeil;
		double div = ((r2 * r2) + (i2 * i2));

		this.realTeil = ((r1 * r2) + (i1 * i2)) / (div);
		this.imagTeil = ((r1 * i2) - (i1 * r2)) / (div);
	}

	public Complex divideWith(Complex z2) {
		divide(z2);
		return this;
	}

	public double betrag() {
		double r = this.realTeil;
		double i = this.imagTeil;

		return Math.sqrt((r * r) + (i * i));
	}

	@Override
	public int hashCode() {
		return Double.valueOf(realTeil).hashCode() * 31 + Double.valueOf(imagTeil).hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj instanceof Complex) {
			Complex other = (Complex) obj;
			return realTeil == other.realTeil && imagTeil == other.imagTeil;
		}
		return false;
	}

	@Override
	public String toString() {
		if (imagTeil == 0.0 || Double.isNaN(imagTeil)) {
			return realTeil + "";
		} else if (realTeil == 0.0 || Double.isNaN(realTeil)) {
			return imagTeil + "i";
		} else if (imagTeil < 0.0) {
			return realTeil + " - " + (-imagTeil) + "i";
		} else {
			return realTeil + " + " + imagTeil + "i";
		}
	}
}
Ungetestet, aber so sollte es gehen.
...sorry, dass ich erschwerenderweise ein paar Methoden umbenannt habe. 😉
...und (ähhh) divideByZero bei komplexen Zahlen? Ich denke, nur wegen solcher Dinge gibt es doch komplexe Zahlen?
 
Zuletzt bearbeitet von einem Moderator:
Jetzt ist mein Ergebnis immer Z1....
Ich dreh bald durch hier....

Das ist jetzt aber selbstverschuldet.

Spacerat hat Dir ganz am Anfang erklärt, wann man "this." nutzt und in Deinem Code sehe ich für "this." keinerlei veranlassung. Würdest Du den Code entsprechend abstrippen und danach mal für 5min an die frische Luft gehen fällt Dir die Lösung wie Schuppen aus den Haaren.

Bernd
 

Neue Themen


Zurück
Oben