Frage zu Konstruktoren und dem this Operator

Ludacriz2006

Mitglied
Hallo,

nehmen wir folgendes an:

Java:
Bruch r1 = new Bruch(4, 5);

Jetzt rufe ich folgendes auf:

Java:
r1.add(new Bruch(4,-3));

wie kann ich nun in der add() Methode auf die Werte 1,5 vom r1 zugreifen?
Habs mit this probiert aber dann sagt der mir "call to this must be first statement in constructor".

Wie kann ich das lösen.

Gruß
 
Bruch hat eine add Methode, die etwa so aussieht:

Java:
class Bruch {
  int zaehler;
  int nenner;
  ...
  public void add(Bruch that) {
     ...
  }
}
Nun kannst du auf die Instanzvariablen des aufrufenden Objekts r1 innerhalb von add einfach mit [c]zaehler[/c] oder [c]this.zaehler[/c] verweisen, und auf die Instanzvariablen des Arguments mit [c]that.zaehler[/c]. Oder anders ausgedrückt: Das aufgerufene add ist sozusagen das add von r1 und "kennt" deshalb seine "eigenen" Variablen.
 
Zeig mal deine Klasse.
Aber grundsätzlich ist das mit this schon richtig. So kannst du z.b. auf die Werte zugreifen:

Java:
public class Bruch {

	private int zaehler;
	private int nenner;
	
	public Bruch(int zaehler, int nenner) {
		this.zaehler = zaehler;
		this.nenner = nenner;
	}
	
	public void add(Bruch b) {
		this.nenner = this.nenner * b.nenner;
		this.zaehler = (this.zaehler * b.nenner) + (b.zaehler * this.nenner);
	}
}
 
> "call to this must be first statement in constructor"
ist eine typische Fehlermeldung für einen Konstruktor, wie es ja auch da steht,

dass du die beim editieren der add()-Methode erhälst ist fragwürdig,
poste doch die add()-Methode bzw. die ganze Klasse,

und was weißt du alles über die Fehlemeldung? Zeilenangabe dabei? Screenshot eine GUI die einen bestimmten Programmteil rot unterstreicht?
 
Java:
public class Bruch {

	private int zaehler;
	private int nenner;
	
	public Bruch(int zaehler, int nenner) {
		this.zaehler = zaehler;
		this.nenner = nenner;
	}
	
	public void add(Bruch b) {
		this.nenner = this.nenner * b.nenner;
		this.zaehler = (this.zaehler * b.nenner) + (b.zaehler * this.nenner);
	}
}

Hey das geht ja super schnell hier.
Danke, ich sehe es jetzt, aber deine add Methode ist fehlerhaft.
Das muss andersrum sein, dann werden Brüche addiert

Java:
this.zaehler = (this.zaehler * b.nenner) + (b.zaehler * this.nenner);
this.nenner = this.nenner * b.nenner;

Vielen Dank
 
Ich hab mal ne andere Frage. Kann eine Konstruktorvariable den Wert eines primitiven Typs annehmen.

Beispiel:

Java:
Peter p = new Peter(2,3);

Kann hier jetzt p ein int oder ein boolean sein?

Danke
 
Nehmen wir an ich habe folgendes:

Java:
Bruch s=null;

Nun will ich aber auf s.ergebnis zugreifen, aber er gibt mir ein NullPointerException aus. (ergebnis ist eine Variable in der Bruch Klasse.)

Wieso ist denn s.ergebnis auch nicht null, wenn doch das Objekt s null ist?
 
Das Objekt ist nicht null.
Mit Bruch s = null löschst Du die Referenz auf das Objekt der Klasse Bruch, die in s gespeichert war.
Damit kannst Du mit s nicht mehr auf das Objekt zugreifen, da es ins Leere zeigt. Daher auch die NullPointerException.
Wenn Du Werte innerhalb des Objektes verändern möchtest, solltest Du in der Klasse Bruch entsprechende setter Methoden implementieren.

Edit:
Achja, Du solltest auch nicht direkt von außen auf Variablen des Objektes zugreifen, sondern hierfür entsprechende getter Methoden implementieren 😉

Java:
class Bruch {
	private int ergebnis;
...
	public int getErgebnis()
	{
		return ergebnis;
	}
	
	public void setEregbis(int wert)
	{
		ergebnis = wert;
	}
}
 
Zuletzt bearbeitet:
Wozu sind die getter Methoden gut? Haben die Vorteile?

Ich mein das ist doch das selbe wenn ich jetzt direkt von der main darauf zugreife oder diese getter Methoden benutze.
 
Der this Operator ruft immer das die aktuelle Instanz auf. Wenn du this() so benutzen willst, dann kannst du es nur als ersten Operator benutzen da es logischerweise den Konstruktor des aktuellen Objekts aufruft.

Java:
class Bruch {
  private int zaehler;
  private int nenner;

  public Bruch() {
    this(3, 8);
  }

  public Bruch(int zaehler, int nenner) {
    this.zaehler = zaehler;
    this.nenner = nenner;
  }

  public void add(Bruch b) {
    this.nenner = this.nenner * b.getNenner();
    this.zaehler = (this.zaehler * b.getNenner) + (b.getZaehler * this.nenner);
  }

  public int getNenner() {
    return this.nenner;
  }

  public int getZaehler() {
    return this.zaehler;
}

Wenn du den Konstruktor mit den beiden Parametern aufrufst kannst du den Zäher bzw. Nenner beim Instanziieren selbst bestimmen, wenn du den Konstruktor ohne Parameter aufrufst wird ein Objekt mit Defaul-Parametern instanziiert. Ich mache das sehr gerne weil ich bei Default-objekten bzw. wenn ich Teste nicht immer Parameter schreiben muss.

Zu deiner Frage mit den Gettern, ich habe in dem Code mal zwei Getter definiert, in der Methode add(...) werden sie auch benutzt. Dadurch das die beiden Instanzvariablen Zaehler und Nenner private sind kann man sie nicht von "außen" aufrufen.

In diesem Beispiel könnten nämlich sonst b.nenner und b.zaehler von "außen" also vom Objekt "this" nicht aufgerufen werden. Durch den Getter bleiben die Variablen aber immer noch schreibgeschützt und können nur gelesen werden. Das ganze nennt sich Kapselung und sollte eigentlich bei jedem OO-Programm verwendet werden. Bei einer einzigen Klasse, die nur aus der main() gesteuert wird mag das noch seltsam wirken aber bei Projekten mit mehreren Klassen hats schon Sinn. Am besten man gewöhnt sich sowas schon im kleinen an, damit mans im Großen nicht vergisst 😉

PS: Setter werden dann im Gegenzug benutzt um Variablenwerte zu setzen 😉
 
Zuletzt bearbeitet:
Wozu sind die getter Methoden gut? Haben die Vorteile?

Ich mein das ist doch das selbe wenn ich jetzt direkt von der main darauf zugreife oder diese getter Methoden benutze.

Setter und Getter haben den Vorteil, dass du kontrollieren kannst, was du bekommst und herausgibst. Stell dir vor, du initialisierst ein Feld ordentlich, und dann schreibt dir jemand einfach null rein - ärgerlich. Oder du willst jemand Lesezugriff auf eine Liste geben - mit dem direkten Zugriff kannst du nicht verhindern, dass die Liste verändert wird, bei einem Getter kannst du z.B. mit Collections.unmodifiableList(list) eine unveränderliche Kopie zurückgeben. Oder deine Werte müssen bestimmte Bedingungen erfüllen, etwa wenn du eine Zeitspanne von-bis mit Date abbildest, und der von-Wert immer kleiner als der bis-Wert sein muss.
 
getter und setter enthalten nicht immer nur Zuweisungen bzw eine return statement.

Es kann durchaus sein, dass ein setter Werte überprüft, dann speichert und gleich noch eine Berechnung auslöst oder einen Counter hochzählt oder oder ....

Es kann aber auch sein, dass die Berechnung nicht im setter sondern erst im getter gemacht wird.

Private Membervariablen zwingen die Benutzer dazu deine Methoden zu verwenden und die bist frei darin, die Berechnung dahin zu verschieben wo es geeigneter ist ....
 
Ein weiterer Vorteil ist die Flexibilität: Stell dir vor du hast eine Klasse Person, die auch das Alter enthält. Später fällt dir ein, dass es praktischer wäre, stattdessen den Geburtstag zu speichern. Bei direktem Zugriff hast du Pech, alle Anwender dieser Klasse müssten sich umstellen. Fragst du das Alter dagegen über einen Getter ab, gibt es kein Problem, er berechnet einfach das Alter aus dem Geburtsdatum, ohne dass sich etwas für den Nutzer der Klasse ändern würde. Getter und Setter schirmen also in einem gewissen Maße "Interna" der Klasse von der Außenwelt ab.
 

Neue Themen


Zurück
Oben