Klassen Rational

Hi Leutz,

ich muss das erste mal einen eigenen Datentyp per Klasse erstellen und benutzen. Folgende Aufgabenstellung:

Schreiben Sie eine nichtausführbare Klasse Rational mit
den privaten Attributen:
- zaehler und nenner

den öffentlichen Konstruktoren:
- Rational()-Der parameterlose Konstruktor soll die rationale Zahl 0 erzeugen.

- Rational(int z, int n)throws IllegalArgumentException
Der parametrisierte Konstruktor soll die Attribute der Klasse Rational mit den übergebenen
Werten initialisieren. Wenn der Konstruktor in einer Weise benutzt wird, der den obigen
Bedingungen widerspricht, soll eine Exception ausgelöst werden und an die aufrufende Methode
weitergereicht und dort behandelt werden.

den öffentlichen Instanz-Methoden:
- String toString()- Repräsentation einer rationalen Zahl als String in der Form
(zaehler/nenner)

- Rational sum( Rational r)- zu einer rationalen Zahl wird r addiert und das Ergebnis
zurückgegeben
- Rational subt(Rational r)- von einer rationalen Zahl wird r subtrahiert und das
Ergebnis zurückgegeben
- Rational mult(Rational r)- eine rationale Zahl wird mit r multipliziert und das
Ergebnis zurückgegeben
- Rational div(Rational r)- eine rationale Zahl wird durch r dividiert und das Ergebnis
zurückgegeben
- void kuerze()- kürzt eine rationale Zahl, indem die Attribute zaehler und nenner durch
den größten gemeinsamen Teiler (ggT) geteilt werden. Der ggT zweier ganzer Zahlen soll als
statische Methode implementiert werden.


Schreiben Sie eine ausführbare Klasse RationalTest. In der main-Methode soll der Benutzer
wiederholt eine Berechnung auswählen. Die Ergebnisse sollen in geeigneter Form auf dem Bildschirm
angezeigt werden...


Sorry erstmal für soviel Text, ich könnte die Aufgabenstellung jedoch nicht knapper darstellen. Zunächst wollte ich fragen, ob duch den modifizierer Private, der Attribute zaehler und nenner,
nicht verhindert wird, dass diese Attribute mit einem Konstruktor in einer anderen Klasse initialisiert werden können? Oder spielt das keine Rolle, weil ich das alles in eine Datei schreibe?

Als nächstes frage ich mich, wie ich z.B. die methode sum benutzen soll, denn ich kann doch nur einer variable vom typ Rational an diese übergeben(Wir müssen die Methodenköpfe so benutzen, wie sie uns laut Aufgabenstellung vorgegeben sind). Mir ist in Bezug auf diese Problematik wahrscheinlich noch irgendein Kniff nicht klar.

Ich hoffe wie immer auf konstruktive Hilfe und danke schonmal im Voraus

grüße simon

p.s. soweit bin ich bis jetzt gekommen:

Java:
import java.util.*

class Rational{

	private int zaehler;
	private int nenner;
	
	Rational(){								
		zaehler = 0;
		nenner = 1;
	}//parameterloser Konstruktor zum initialiesieren des rationalen wertes null
	
	Rational(int z, int n){
		zaehler = z;
		nenner = n;
	}//parametrisierter Konstruktor zum initialisieren einer rationalen Zahl mit den Werten für Zähler und Nenner
	
	String toString(){
		String bruch;
		String = ""+zaehler+"/"+nenner;
		return bruch;
	}//Methode, die einen String mit dem Bruch erzeugt
	
	Rational sum (Rational r){
	
	??????????
	
	}
		
	
	static int ggT(int a, int b) { 
		while(a != b){
			if (a > b)
			a = a - b;
			else b = b - a;
		}
		return a;
    }//Berechnet den ggT zweier Zahlen
	
	static int kgV(int a, int b,ggT) { 
		return a * (b / ggT(a,b));  
    }//Berechnet das ggV zweier Zahlen
	
	}//Rational
	
	class RationalTest{
	
	public static void main(String [] args){
	
		do{
			int auswahl;
			int zaehler;
			int zaehler2;
			int nenner;
			int nenner2;
			int zaehlerneu;
			Rational ergebnis;
			
			System.out.println("Bitte waehlen Sie aus:");
			System.out.println("1 - addieren ");
			System.out.println("2 - subtrahieren ");
			System.out.println("3 - multiplizieren ");
			System.out.println("4 - dividieren ");
			System.out.println("Bitte geben Sie den Zaehler der ersten Zahl ein: ");
			zaehler = in.nextInt;
			System.out.println("Bitte geben Sie den Nenner der ersten Zahl ein: ");
			nenner = in.nextInt;
			System.out.println("Bitte geben Sie den Zaehler der zweiten Zahl ein: ");
			zaehler2 = in.nextInt;
			System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
			nenner2 = in.nextInt;
			
			switch(auswahl){
			
				case 1: if((zaehler==0)&&(nenner==1){						//Darstellung einer Null	
							Rational r1 = new rational();					//parameterloser Konstruktor erstellt die null	
						if((zaehler2==0)&&(nenner2==1){
							Rational r2 = new rational();
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
						
						ergebnis = sum(r1);//?????????
						
						
						/*ggT = ggT(nenner,nenner2);
						kgV = kgV(nenner,nenner2,ggT);
						summand = (kgV/nenner)*zaehler;
						summand2 = (kgV/nenner2)*zaehler2;
						zaehlerneu = summand + summand2;
						*/
					
			}//switch
					
			System.out.println("Möchten sie eine weitere Berechnung durchführen(j,n): ");
			eingabe = in.nextChar();
		}//do
		while(eingabe == j);
	}//main
	
	}//RationalTest
 
Zuletzt bearbeitet von einem Moderator:
N

nillehammer

Gast
Sorry erstmal für soviel Text, ich könnte die Aufgabenstellung jedoch nicht knapper darstellen. Zunächst wollte ich fragen, ob duch den modifizierer Private, der Attribute zaehler und nenner,
nicht verhindert wird, dass diese Attribute mit einem Konstruktor in einer anderen Klasse initialisiert werden können? Oder spielt das keine Rolle, weil ich das alles in eine Datei schreibe?
Nein, wenn Dein Konstruktor für Rational public ist, kannst Du ihn von überall aus aufrufen und auch die Parameter übergeben. Die Initialisierung passiert ja innerhalb des Konstruktors, von wo aus Du auch Zugriff auf die privaten Felder hast. Mit "in eine Datei schreiben" hat das ganze nichts zu tun.

In Deinem Beispielcode sind die Konstruktoren übribens default visible, d.h. sie sind nur für Klassen innerhalb des selben Packages sichtbar. Deine Testklasse müsste also im selben Package liegen.

Als nächstes frage ich mich, wie ich z.B. die methode sum benutzen soll, denn ich kann doch nur einer variable vom typ Rational an diese übergeben(Wir müssen die Methodenköpfe so benutzen, wie sie uns laut Aufgabenstellung vorgegeben sind). Mir ist in Bezug auf diese Problematik wahrscheinlich noch irgendein Kniff nicht klar.
Wenn ich richtig erinnere, addiert man Brüche, indem man sie so erweitert, dass der neue Nenner durch beide ursprünglichen teilbar ist. Die (erweiterten) Zähler werden dann einfach addiert.

Am einfachsten ist, die beiden Nenner mit ein ander mal zu nehmen, so hat man zwar im Zweifel nicht den kleinsten, aber einen, der geht.

Java:
Rational sum (Rational r){

   final int newNenner = this.nenner * r.nenner;

   final int newThisZaehler = this.zaehler * r.nenner;

   final int newRZaehler = r.zaehler * this.nenner;

   final int zaehlerSum = newThisZaehler + newRZaehler; 

   return new Rational(zaehlerSum, newNenner);
}

P.S. Mir war aus der Aufgabenstellung nicht ganz klar, ob bei sum() die Instanz, auf der die Methode aufgerufen wird, verändert werden soll, oder ob es nur um das Ergebnis geht. Ich habe mich für zweiteres Entschieden und darum eine neue Instanz zurück gegeben. Falls das nicht gewünscht ist, musst Du die Methodenlokalen Variablen durch die entsprechenden Instanzvariablen ersetzen und
Code:
this
zurück geben.
 
Zuletzt bearbeitet von einem Moderator:
Danke, das wahr schonmal sehr hilfreich. Habe die Konstruktoren nun mit Public modifiziert. Ich verstehe aber leider nicht, wie ich mit Hilfe von this. zwei verschieden Werte behandele. Das heißt, wie sieht denn meine Übergabe in der main aus?
Eigentlich dachte ich verstanden zu haben, was bei benutzen von this geschieht...
Ich muss es wohl nochmal verstehen ^^.

Greeetz

simon
 
N

nillehammer

Gast
Ich verstehe aber leider nicht, wie ich mit Hilfe von this. zwei verschieden Werte behandele.
Verstehe die Frage nicht, deswegen mal ins Blaue hinein geantwortet, vielleicht hilft's. Mit dem Schlüsselwort
Code:
this
sagst Du eigentlich nur, dass Du auf irgendwas in der aktuellen Instanz ("in mir selbst") zugreifen willst. Z.B. in dieser Zeile:
Java:
/*
 * Wir haben zwei mal eine Variable namens "nenner".
 * Einmal unsere eigene (this.nenner) und einmal die
 * des übergebenen Parameters (r.nenner).
 * Durch voranstellen von this/r halten wir diese auseinander.
 */
final int newNenner = this.nenner * r.nenner;
Das heißt, wie sieht denn meine Übergabe in der main aus?
Das verstehe ich nun überhaupt nicht. In der main-Methode gibt es überhaupt kein
Code:
this
, weil sie statisch ist und sich der Code deswegen nicht auf eine aktuelle Instanz beziehen kann.
 
Anscheinend bin ich da noch ein ganz schön großen Sprung weg vom Verständnis. Ich möchte doch vom Benutzer in der main Werte eingeben lassen. Dann erzeuge ich per Konstruktor zwei Variablen des Types Rational, die jeweils eine rationale Zahl beinhalten (ab Zeile 75). So weit so gut. Woher weiß denn nun meine Methode sum, welche der beiden Instanzvariablen zaehler bzw. nenner ich mit this anspreche. Also sozusagen, welche jetzt die aktuelle Instanz ist? Sorry das ich mich da so schwer tuhe, aber ich sehe diese methode halt immernoch so, als ob ich ihr zweimal jeweils den Nenner und den Zähler übergeben müsste, sprich einmal das Objekt mit der ersten rationalen Zahl und einmal das mit der zweiten. Deswegen habe ich mich ja auch gefragt, warum ich nur eine Variable vom Typ Rational an die Methode sum übergeben darf.

Danke nochmal für deine Mühe, sowas ist eig. unbezahlbar. Vielleicht weißt du jetzt wo bei meinem Verständnis der Haken ist.

Viel Spaß beim Spiel heute!!! Drücken wir die Daumen.

Ich werd per handy nochmal reinschauen, vielleicht hast du ja das unmögliche geschafft, und ich kapiers endlich.

grüße simon
 
N

nillehammer

Gast
Woher weiß denn nun meine Methode sum, welche der beiden Instanzvariablen zaehler bzw. nenner ich mit this anspreche.
Du rufst Die Methode sum ja auf einer Instanz auf. Das ist die Instanz, auf die this zeigt. Am Beispiel Deiner (etwas veränderten) main-Methode:
[JAVA=79]
Rational r1 = new Rational(zaehler, nenner);
Rational r2 = new Rational(zaehler2, nenner2);
/*
* Hier wird sum auf r1 aufgerufen, d.h.
* this.zaehler und this.nenner innerhalb der
* Methode beziehen sich auf die Variablen von r1
*/
Rational ergebnis1 = r1.sum(r2);

/*
* Hier wird sum auf r2 aufgerufen, d.h.
* this.zaehler und this.nenner innerhalb der
* Methode beziehen sich auf die Variablen von r2
*/
Rational ergebnis2 = r2.sum(r1);

[/code]

Sorry das ich mich da so schwer tuhe, aber ich sehe diese methode halt immernoch so, als ob ich ihr zweimal jeweils den Nenner und den Zähler übergeben müsste, sprich einmal das Objekt mit der ersten rationalen Zahl und einmal das mit der zweiten.
Ja, eine Methode
Code:
public static Rational sum(Rational first, Rational second)
würde meiner Meinung nach auch mehr Sinn machen. Aber die Aufgabenstellung ist ja nunmal eine Andere.

[EDIT]
Wenn ich mir die Aufgabe aus Deinem ersten Post jetzt so durchlese, glaube ich, dass bei den ganzen Methoden doch die Instanzvariablen verändert werden sollen. Meine Implementierung wäre dann ensprechend anzupassen. Frag einfach mal den Prof.
[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
Hi nochmal,

bin zwar schon ein stück weiter, aber es gibt ein großes Problem beim compilieren. Ich erzeuge in der main ein Objekt ergebnis der Klasse Rational. Nun führe ich wie gesagt eine Methode, z.B. sum, auf der Instanz r1 auf. Ich will das Ergebnis der Rechnung an die Variable ergebnis übergeben. Allerdings bekomme ich vom Compiler an allen Stellen an denen die Variable ergebnis benutzt wird, die Fehlermeldung "cannot find Symbol". Was mache beim erstellen des Objekts falsch? Ich erzeuge es ja mit einem Konstruktor, der den Instanzvariablen die werte 0 und 1 zuweist. Kann ich diese Werte per Zuweisung der ausgeführten Methode nicht überschreiben, oder woran liegt es?

Java:
import java.util.*;

class Rational{

	private int zaehler;
	private int nenner;
	
	public Rational(){								
		zaehler = 0;
		nenner = 1;
	}//parameterloser Konstruktor zum initialiesieren des rationalen wertes null
	
	public Rational(int z, int n){
		zaehler = z;
		nenner = n;
	}//parametrisierter Konstruktor zum initialisieren einer rationalen Zahl mit den Werten für Zähler und Nenner
	
	public String toString(){
		String bruch;
		bruch = ""+ergebnis.zaehler+"/"+ergebnis.nenner;
		return bruch;
	}//Methode, die einen String mit dem Bruch erzeugt
	
	Rational sum (Rational r){
 
    final int newNenner = this.nenner * r.nenner;
 
    final int newThisZaehler = this.zaehler * r.nenner;
 
    final int newRZaehler = r.zaehler * this.nenner;
 
    final int zaehlerSum = newThisZaehler + newRZaehler; 
 
    return new Rational(zaehlerSum, newNenner);
	}
	
	Rational subt (Rational r){
	
	final int newNenner = this.nenner * r.nenner;
 
    final int newThisZaehler = this.zaehler * r.nenner;
 
    final int newRZaehler = r.zaehler * this.nenner;
 
    final int zaehlerSum = newThisZaehler - newRZaehler; 
 
    return new Rational(zaehlerSum, newNenner);
	}
	
	Rational mult (Rational r){
	
	final int newNenner = this.nenner * r.nenner;
	
	final int newZaehler = this.zaehler * r.zaehler;
	
	return new Rational(newZaehler, newNenner);
	}
	
	Rational div (Rational r){
	
	final int newNenner = this.nenner * r.zaehler;
	
	final int newZaehler = this.zaehler * r.nenner;
	
	return new Rational(newZaehler, newNenner);
	}
	
	void kuerze(){
	
	int ggT;
	ggT = ggT(ergebnis.zaehler,ergebnis.nenner);
	ergebnis.zaehler = ergebnis.zaehler/ggT;
	ergebnis.nenner = ergebnis.nenner/ggT;
	
	}//kuerze
		
	static int ggT(int a, int b) { 
		while(a != b){
			if (a > b)
			a = a - b;
			else b = b - a;
		}
		return a;
    }//Berechnet den ggT zweier Zahlen
	
	}//Rational
	
	class RationalTest{
	
	public static void main(String [] args){
			Scanner in = new Scanner(System.in);
			Rational ergebnis = new Rational();			
			int auswahl;
			int zaehler;
			int zaehler2;
			int nenner;
			int nenner2;
			int zaehlerneu;
			String fertig;
		do{
			
		
			System.out.println("Bitte waehlen Sie aus:");
			System.out.println("1 - addieren ");
			System.out.println("2 - subtrahieren ");
			System.out.println("3 - multiplizieren ");
			System.out.println("4 - dividieren ");
			System.out.println("Bitte geben Sie den Zaehler der ersten Zahl ein: ");
			zaehler = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der ersten Zahl ein: ");
			nenner = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der zweiten Zahl ein: ");
			zaehler2 = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
			nenner2 = in.nextInt();
			
			switch(auswahl){
			
				case 1: if((zaehler==0)&&(nenner==1)){						//Darstellung einer Null	
							Rational r1 = new Rational();					//parameterloser Konstruktor erstellt die null	
						}
						if((zaehler2==0)&&(nenner2==1)){
							Rational r2 = new Rational();
						}
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
			
						ergebnis = r1.sum(r2);
						kuerze();
						fertig = toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
				
				case 2: if((zaehler==0)&&(nenner==1)){						//Darstellung einer Null	
							Rational r1 = new Rational();					//parameterloser Konstruktor erstellt die null	
						}
						if((zaehler2==0)&&(nenner2==1)){					
							Rational r2 = new Rational();
						}
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
						
						ergebnis = r1.subt(r2);
						kuerze();
						fertig = toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
						
				case 3: if((zaehler==0)&&(nenner==1)){						//Darstellung einer Null	
							Rational r1 = new Rational();					//parameterloser Konstruktor erstellt die null	
						}
						if((zaehler2==0)&&(nenner2==1)){
							Rational r2 = new Rational();
						}
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
						
						ergebnis = r1.mult(r2);
						kuerze();
						fertig = toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
						
				case 4: if((zaehler==0)&&(nenner==1)){						//Darstellung einer Null	
							Rational r1 = new Rational();					//parameterloser Konstruktor erstellt die null	
						}
						if((zaehler2==0)&&(nenner2==1)){
							Rational r2 = new Rational();
						}
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
						
						ergebnis = r1.div(r2);
						kuerze();
						fertig = toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
			}//switch
			
			System.out.println("Moechten sie eine weitere Berechnung durchfuehren?(1=ja,0=nein): ");
			auswahl = in.nextInt();
			
		}//do
		while(auswahl == 1);
		
	}//main
	
	}//RationalTest
 
Zuletzt bearbeitet:
B

buzz!dev

Gast
wenn du "ergebnis" in deiner Main erzeugst, dann gilt es selbstverständlich auch nur dort und hat in deiner Klasse Rational nichts verloren.
 

AquaBall

Top Contributor
Mann da sind ja massig fehler drin!

Welches toString soll denn verwendet werden?

Wozu die Variable fertig?

Was sollen die final's bei temporären Variablen?

Code:
kuerze();
funktioniert so nicht, das ist eine Methode der Klasse Rational!
(Außerdem könnte kürze statt void auch das Ergebnis zurückgeben, dann kannst du direkt damit rechen.)

Wozu das?:
Java:
  case 4: if((zaehler==0)&&(nenner==1)){      //Darstellung einer Null    
          Rational r1 = new Rational();        //parameterloser Konstruktor erstellt die null  
      }
Erstens wird zwei Zeilen später der Kunstruktor nochmal aufgerufen,
zweitens ist r1 im if lokal, wird also sofort wieder entsorgt!

...


PS: Formatiere den Text besser, dann findest du (und alle die helfen sollen) dich besser zurechet!
(Und schmeiß die doofen Leerzeilen raus)

Java:
    Rational sum (Rational r){
        int newNenner = this.nenner * r.nenner;
        return new Rational(this.zaehler * r.nenner + r.zaehler * this.nenner, newNenner);
    }

Vorallem, wenn du an dieser Stelle richtig formatierst, sollten dir einige Zugriffsfehler auffallen:
Java:
...
    /** Berechnet den ggT zweier Zahlen **/
    public int ggT(int a, int b) { 
        while(a != b){
            if (a > b) a -=b;
            else       b -=a;
        }
        return a;
    }//ggT
}//Rational

// ACHTUNG!
// Hier richtig einrücken! Hier(!) beginnt eine neue Klasse!
// -> alles obige (z.B, kuerze und toString) kannst du NUR über 'Rational'-Instanzen aufrufen.
    
class RationalTest{
    
    public static void main(String [] args){
...
 
Zuletzt bearbeitet:
Welches toString soll denn verwendet werden?
Diese frage verstehe ich nun wirklich nicht. Meinst du damit, worauf es verwendet werden soll? Müsste es also folgendermaßén lauten: z.B. ergebnis.toString(); ?

Wozu die Variable fertig?
Diese wollte ich eben benutzen, um den übergebenen String abzufangen.

Was sollen die final's bei temporären Variablen?
Die hab ich leider einfach mal stupide vom vorpost übernommen.

Das ist natürlich völlig überflüssig. Ich müsste dem Benutzer ja nur mitteilen, dass er für den Zaehler eine Null und für den Nenner eine 1 eingeben muss, um eine Null zu erzeugen. Aber in der Aufgabenstellung wird leider verlangt, dass man das mit dem parameterlosen Konstruktor eben dieser Form lösen soll. Ich muss alle Methodenköpfe und Konstruktoren aus der Aufgabenstellung übernehmen.

Erstens wird zwei Zeilen später der Kunstruktor nochmal aufgerufen,
zweitens ist r1 im if lokal, wird also sofort wieder entsorgt!
Wie soll ich sonst an dieser Stelle eine Fallunterscheidung gemäß der Aufgabenstellung einbauen?
Außerdem könnte kürze statt void auch das Ergebnis zurückgeben, dann kannst du direkt damit rechen
Das darf ich leider nicht, weil ich die Methodenköpfe wie gesagt aus der Aufgabenstellung übernehmen muss.

Ich habe die Methoden kuerze und toString jetzt über die Instanz ergebnis des Typs Rational ausführen lassen.

Ich weiß immernoch nicht, wo ich die das Objekt ergebnis der Klasse Rational erzeugen soll, um es verwenden zu können. Erzeuge ich es in der Klasse Rational, bekomme ich immernoch die Fehlermeldungen.

Boah, ist das zäh, danke nochmal,

grüße

simon
Java:
import java.util.*;

class Rational{

	private int zaehler;
	private int nenner;
	
	public Rational(){								
		zaehler = 0;
		nenner = 1;
	}//parameterloser Konstruktor zum initialiesieren des rationalen wertes null
	public Rational(int z, int n){
		zaehler = z;
		nenner = n;
	}//parametrisierter Konstruktor zum initialisieren einer rationalen Zahl mit den Werten für Zähler und Nenner
	public String toString(){
		String bruch;
		bruch = ""+ergebnis.zaehler+"/"+ergebnis.nenner;
		return bruch;
	}//Methode, die einen String mit dem Bruch erzeugt
	
	Rational sum (Rational r){
		int newNenner = this.nenner * r.nenner;
		int newThisZaehler = this.zaehler * r.nenner;
	 int newRZaehler = r.zaehler * this.nenner;
	 int zaehlerSum = newThisZaehler + newRZaehler; 
	return new Rational(zaehlerSum, newNenner);
	}
	
	Rational subt (Rational r){
		int newNenner = this.nenner * r.nenner;
		int newThisZaehler = this.zaehler * r.nenner;
		int newRZaehler = r.zaehler * this.nenner;
		int zaehlerSum = newThisZaehler - newRZaehler; 
	return new Rational(zaehlerSum, newNenner);
	}
	
	Rational mult (Rational r){
		int newNenner = this.nenner * r.nenner;
		int newZaehler = this.zaehler * r.zaehler;
	return new Rational(newZaehler, newNenner);
	}
	
	Rational div (Rational r){
		int newNenner = this.nenner * r.zaehler;
		int newZaehler = this.zaehler * r.nenner;
	return new Rational(newZaehler, newNenner);
	}
	
	void kuerze(){
	int ggT;
	ggT = ggT(ergebnis.zaehler,ergebnis.nenner);
	ergebnis.zaehler = ergebnis.zaehler/ggT;
	ergebnis.nenner = ergebnis.nenner/ggT;
	
	}//kuerze
		
	static int ggT(int a, int b) { 
		while(a != b){
			if (a > b)
			a = a - b;
			else b = b - a;
		}
		return a;
    }//Berechnet den ggT zweier Zahlen
	
	}//Rational
	
class RationalTest{
	
	public static void main(String [] args){
			Scanner in = new Scanner(System.in);		
			int auswahl;
			int zaehler;
			int zaehler2;
			int nenner;
			int nenner2;
			int zaehlerneu;
			String fertig;
		do{
			
		
			System.out.println("Bitte waehlen Sie aus:");
			System.out.println("1 - addieren ");
			System.out.println("2 - subtrahieren ");
			System.out.println("3 - multiplizieren ");
			System.out.println("4 - dividieren ");
			System.out.println("Bitte geben Sie den Zaehler der ersten Zahl ein: ");
			zaehler = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der ersten Zahl ein: ");
			nenner = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der zweiten Zahl ein: ");
			zaehler2 = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
			nenner2 = in.nextInt();
			
			switch(auswahl){
			
				case 1: if((zaehler==0)&&(nenner==1)){						//Darstellung einer Null	
							Rational r1 = new Rational();					//parameterloser Konstruktor erstellt die null	
						}
						if((zaehler2==0)&&(nenner2==1)){
							Rational r2 = new Rational();
						}
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
						ergebnis = r1.sum(r2);
						ergebnis.kuerze();
						fertig = ergebnis.toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
				
				case 2: if((zaehler==0)&&(nenner==1)){						//Darstellung einer Null	
							Rational r1 = new Rational();					//parameterloser Konstruktor erstellt die null	
						}
						if((zaehler2==0)&&(nenner2==1)){					
							Rational r2 = new Rational();
						}
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
						ergebnis = r1.subt(r2);
						ergebnis.kuerze();
						fertig = ergebnis.toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
						
				case 3: if((zaehler==0)&&(nenner==1)){						//Darstellung einer Null	
							Rational r1 = new Rational();					//parameterloser Konstruktor erstellt die null	
						}
						if((zaehler2==0)&&(nenner2==1)){
							Rational r2 = new Rational();
						}
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
						ergebnis = r1.mult(r2);
						ergebnis.kuerze();
						fertig = ergebnis.toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
						
				case 4: if((zaehler==0)&&(nenner==1)){						//Darstellung einer Null	
							Rational r1 = new Rational();					//parameterloser Konstruktor erstellt die null	
						}
						if((zaehler2==0)&&(nenner2==1)){
							Rational r2 = new Rational();
						}
						Rational r1 = new Rational(zaehler, nenner);		
						Rational r2 = new Rational(zaehler2, nenner2);
						ergebnis = r1.div(r2);
						ergebnis.kuerze();
						fertig = ergebnis.toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
			}//switch
			
			System.out.println("Moechten sie eine weitere Berechnung durchfuehren?(1=ja,0=nein): ");
			auswahl = in.nextInt();
			
		}//do
		while(auswahl == 1);
		
	}//main
	
}//RationalTest
 
Zuletzt bearbeitet:

HimBromBeere

Top Contributor
Diese frage verstehe ich nun wirklich nicht. Meinst du damit, worauf es verwendet werden soll? Müsste es also folgendermaßén lauten: z.B. ergebnis.toString(); ?
So is es.

Ich weiß immernoch nicht, wo ich die das Objekt ergebnis der Klasse Rational erzeugen soll, um es verwenden zu können. Erzeuge ich es in der Klasse Rational, bekomme ich immernoch die Fehlermeldungen.
In der main natürlich. Du legst zuerst deine beiden Rationalen
Code:
r1
und
Code:
r2
an, zuletzt eine dritte mit namen
Code:
ergebnis
, welcher du
Code:
r1.sum(r2)
zuweist. Zuletzt rufst du zum Kürzen des Ergebnisses dessen
Code:
kurze
-Methode und zum Ausgeben seine
Code:
toString
auf:
Java:
main(...) {
    Rational r1 = new Rational(2.0, 3.0);
    Rational r2 = new Rational(4.0, 5.0);
    Rational ergebnis = r1.sum(r2);
    ergebnis.kuerze();
    System.out.println(ergebnis.toString());
}
Wobei du dir den expliziten Aufruf von toString auch schenken kannst, das ist Geschmackssache.

[EDIT]Wenn ich das in deiner
Code:
main
richtig sehe, kommt der Fehler des nicht gefundenen Symbols einfach daher, dass du
Code:
ergebnis
nicht definiert hast. Wie bereits erwähnt muss das in der
Code:
main
geschehen.[/EDIT]

[EDIT]Deine toString-Methode kannste mal bissl kürzen:
Java:
public String toString(){
    return this.zaehler + "/" + this.nenner; // die Verwendung von ergebnis geht hier nicht, weil der Klasse Rational diese Variable 
                                            // nicht bekannt ist (und auch nicht sein sollte)
}//Methode, die einen String mit dem Bruch erzeugt
[/EDIT]
 
Zuletzt bearbeitet:
N

nillehammer

Gast
AquaBall hat gesagt.:
Was sollen die final's bei temporären Variablen?
Die kommen aus meinem Code. Ich mach immer alle Variablen final, bei denen ich weiß, dass ich sie im weiteren Verlauf des Codes nicht verändern will (dazu ist final ja da). So sieht man im Code sofort, dass die entsprechende Variable nur weiter verwendet, aber nicht neu belegt wird. Außerdem schütze ich mich vor eigener Schludrigkeit, denn der Compiler meckert sofort, wenn ich einer solchen Variable aus Versehen doch mal einen neuen Wert zuweise. Ist vielleicht etwas übertrieben, aber das ist der Grund.
 
B

bone2

Gast
wenn zähler und nenner private sind, kansnt du die nicht mit
Code:
r.nenner
erreichen. du brauchst getter und setter.
Code:
int newNenner = this.nenner * r.getNenner();
 

HimBromBeere

Top Contributor
bone2 hat gesagt.:
wenn zähler und nenner private sind, kansnt du die nicht mit r.nenner erreichen. du brauchst getter und setter.
Brauchst du nicht, solange du dich in der selben Klasse befindest.

Java:
public class Foo {	
	public static void main(String[] args) {
    	MyClass test = new MyClass(1, 2);
    	test.doSomething(new MyClass(3, 4));   	
	}
}

class MyClass{
	private int t1, t2;
	
	MyClass(int t1, int t2) {
		this.t1 = t1;
		this.t2 = t2;
	}
	
	void doSomething(MyClass other) {
		System.out.println(this.t1 + "\t" + other.t2); // this actually works, try it...
	}
}
 
Zuletzt bearbeitet:

AquaBall

Top Contributor
Die kommen aus meinem Code. Ich mach immer alle Variablen final, bei denen ich weiß, dass ich sie im weiteren Verlauf des Codes nicht verändern will (dazu ist final ja da). So sieht man im Code sofort, dass die entsprechende Variable nur weiter verwendet, aber nicht neu belegt wird. Außerdem schütze ich mich vor eigener Schludrigkeit, denn der Compiler meckert sofort, wenn ich einer solchen Variable aus Versehen doch mal einen neuen Wert zuweise. Ist vielleicht etwas übertrieben, aber das ist der Grund.

Mir ist schon klar, was final macht, aber ob das sinnvoll ist ist 'ne andere Frage:
Java:
Rational sum (Rational r){
   final int newNenner = this.nenner * r.nenner;
   final int newThisZaehler = this.zaehler * r.nenner;
   final int newRZaehler = r.zaehler * this.nenner;
   final int zaehlerSum = newThisZaehler + newRZaehler; 
   return new Rational(zaehlerSum, newNenner);
}

Nach deinem Konzept müsste man Java um-erfinden:
Neue Basis:
  • Alle Variablen sind grundsätzlich
    Code:
    final
    , und jede Ausnahme müsste als
    Code:
    volatil
    gekennzeichnet werden.
  • Und künftig heißen sie nicht mehr Vari-ablen, sondern Stati-ablen
Na mir soll's egal sein, wenn jemand darauf steht.
 

AquaBall

Top Contributor
Da ist noch immer dieser Bullshit drin:
Java:
if((zaehler2==0)&&(nenner2==1)){
  Rational r2 = new Rational();
}

(Nicht das
Code:
if
, das könnte ja einen Sinn haben, aber : ... )
... diese Variable
Code:
r2
ist lokal!
Sie wird erzeugt und SOFORT (unbenutzt) entsorgt! Völlig unnütz!
Das ganze Konstrukt kann ersatzlos gestrichen werden!!
(oder muss umgeschrieben werden, wenn's etwas sinnvolles tun soll.)

Zumal ja die folgende Zeile:
Java:
Rational r2 = new Rational(zaehler2, nenner2);
exakt das Selbe und Richtige macht.

Dein Standard-Konstuktor () ist ja eh richtig.
Das heißt nicht, dass du bei 0/1 den allgemeinen Konstruktor (n,z) nicht verwenden DARFST.
Und wenn du aber unbedingt willst, dann must du es anders aufbauen!
 
Ok, es war ein langer weg bis hierhin, aber langsam hab ich das Prinzip verstanden. Warum erscheint beim ausführen, nach dem fehlerfreien compilieren, die Fehlermeldung "java.lang.NoSuchMEthodError: main "? Muss ich die main irwie gesondert ausführen bzw. compilieren?

Java:
import java.util.*;

class Rational{

	private int zaehler;
	private int nenner;
	
	public Rational(){								
		zaehler = 0;
		nenner = 1;
	}//parameterloser Konstruktor zum initialiesieren des rationalen wertes null
	public Rational(int z, int n){
		zaehler = z;
		nenner = n;
	}//parametrisierter Konstruktor zum initialisieren einer rationalen Zahl mit den Werten für Zähler und Nenner
	public String toString(){
		return this.zaehler + "/" + this.nenner;
	}//Methode, die einen String mit dem Bruch erzeugt
	
	Rational sum (Rational r){
		int newNenner = this.nenner * r.nenner;
		int newThisZaehler = this.zaehler * r.nenner;
	 int newRZaehler = r.zaehler * this.nenner;
	 int zaehlerSum = newThisZaehler + newRZaehler; 
	return new Rational(zaehlerSum, newNenner);
	}
	
	Rational subt (Rational r){
		int newNenner = this.nenner * r.nenner;
		int newThisZaehler = this.zaehler * r.nenner;
		int newRZaehler = r.zaehler * this.nenner;
		int zaehlerSum = newThisZaehler - newRZaehler; 
	return new Rational(zaehlerSum, newNenner);
	}
	
	Rational mult (Rational r){
		int newNenner = this.nenner * r.nenner;
		int newZaehler = this.zaehler * r.zaehler;
	return new Rational(newZaehler, newNenner);
	}
	
	Rational div (Rational r){
		int newNenner = this.nenner * r.zaehler;
		int newZaehler = this.zaehler * r.nenner;
	return new Rational(newZaehler, newNenner);
	}
	
	void kuerze(){
	int ggT;
	ggT = ggT(this.zaehler,this.nenner);
	this.zaehler = this.zaehler/ggT;
	this.nenner = this.nenner/ggT;
	
	}//kuerze
		
	static int ggT(int a, int b) { 
		while(a != b){
			if (a > b)
			a = a - b;
			else b = b - a;
		}
		return a;
    }//Berechnet den ggT zweier Zahlen
	
	}//Rational
	
class RationalTest{
	
	public static void main(String [] args){
			Scanner in = new Scanner(System.in);		
			int auswahl=0;
			int zaehler;
			int zaehler2;
			int nenner;
			int nenner2;
			int zaehlerneu;
			String fertig;
		do{
			System.out.println("Bitte waehlen Sie aus:");
			System.out.println("1 - addieren ");
			System.out.println("2 - subtrahieren ");
			System.out.println("3 - multiplizieren ");
			System.out.println("4 - dividieren ");
			System.out.println("Bitte geben Sie den Zaehler der ersten Zahl ein: ");
			zaehler = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der ersten Zahl ein: ");
			nenner = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der zweiten Zahl ein: ");
			zaehler2 = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
			nenner2 = in.nextInt();
			Rational r1 = new Rational(zaehler, nenner);		
			Rational r2 = new Rational(zaehler2, nenner2);
			Rational ergebnis = r1.sum(r2);
			
			switch(auswahl){
			
				case 1: ergebnis = r1.sum(r2);
						ergebnis.kuerze();
						fertig = ergebnis.toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
				
				case 2:	ergebnis = r1.subt(r2);
						ergebnis.kuerze();
						fertig = ergebnis.toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
						
				case 3: ergebnis = r1.mult(r2);
						ergebnis.kuerze();
						fertig = ergebnis.toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
						
				case 4:	ergebnis = r1.div(r2);
						ergebnis.kuerze();
						fertig = ergebnis.toString();
						System.out.println("Das Ergebnis lautet:" + fertig);
						break;
			}//switch
			
			System.out.println("Moechten sie eine weitere Berechnung durchfuehren?(1=ja,0=nein): ");
			auswahl = in.nextInt();
			
		}//do
		while(auswahl == 1);
		
	}//main
	
}//RationalTest
 
Zuletzt bearbeitet:

AquaBall

Top Contributor
Dein main liegt in Klasse
Code:
RationalTest
.
Also muss das ganze unter
Code:
RationalTest.java
gespeichert sein!

PS: Sprechende Namen machst du nun ja sauber, auch für Zwischenergebnisse.
Java:
    Rational mult (Rational r){
        int newNenner = this.nenner * r.nenner;
        int newZaehler = this.zaehler * r.zaehler;
    return new Rational(newZaehler, newNenner);
    }

Aber für so einfache Codes würd ich doch kompakter schreiben:
Java:
    Rational mult (Rational r){
        return new Rational(this.zaehler * r.zaehler, this.nenner * r.nenner);
    }

Dannn hast du noch immer ein paar Formatierungsfehler drin.
(Auch die return's gehören eingerückt!)

Dann geht das hier noch Java-mäßiger:
Java:
    static int ggT(int a, int b) { 
        while(a != b){
            if (a > b) a -= b;
            else       b -= a;
        }
        return a;
    }//Berechnet den ggT zweier Zahlen

Bei der Definition von
Code:
Rational ergebnis = r1.sum(r2);
hast du eine nicht nachvollziehbare Berechnung.
GENAU HIER könntest du deinen standardKonstruktor anwenden: (ist aber nicht nötig.)
Java:
            Rational ergebnis;  // oder:   = new Rational();

Und deine Ausgabe musst du nicht 4 mal coden, sondern reicht 1 x nach dem Switch.
(auch ein default macht sich immer gut)
Java:
            switch(auswahl){
                case 1: ergebnis = r1.sum(r2);  break;
                case 2: ergebnis = r1.subt(r2); break;
                case 3: ergebnis = r1.mult(r2); break;
                case 4: ergebnis = r1.div(r2);  break;
                default: ergebnis = new Rational(); // (... damit kürze unten nicht stirbt.)
            }//switch
            ergebnis.kuerze();
            System.out.println("Das Ergebnis lautet:" + ergebnis);  //(toString erfolgt automatisch)
 
Zuletzt bearbeitet:
W

Wishmaster51

Gast
Nebenbei: Der
Code:
inputStream in
in main muss noch mit
Code:
in.close();
geschlossen werden.

PS: Die Auswahl des Nutzers wird ja nirgens abgefragt.
 
Zuletzt bearbeitet von einem Moderator:
Habs echt soweit geschafft... Wenn du mir jetzt noch einmal erklärst, warum ich hier ein default brauche, um kuerze() nicht verhungern zu lassen und warum toString automatisch ausgeführt wird, wär ich dir ein weiteres Mal dankbar!

Nebenbei: Der inputStream in in main muss noch mit in.close(); geschlossen werden.
???

PS: Die Auswahl des Nutzers wird ja nirgens abgefragt
Hab ich beim test auch gemerkt ;).

Java:
import java.util.*;

class Rational{

	private int zaehler;
	private int nenner;
	
	public Rational(){								
		zaehler = 0;
		nenner = 1;
	}//parameterloser Konstruktor zum initialiesieren des rationalen wertes null
	
	public Rational(int z, int n){
		zaehler = z;
		nenner = n;
	}//parametrisierter Konstruktor zum initialisieren einer rationalen Zahl mit den Werten für Zähler und Nenner
	
	public String toString(){
		return this.zaehler + "/" + this.nenner;
	}//Methode, die einen String mit dem Bruch erzeugt
	
	Rational sum (Rational r){
		int newThisZaehler = this.zaehler * r.nenner;
		int newRZaehler = r.zaehler * this.nenner;
		return new Rational(newThisZaehler + newRZaehler, this.nenner * r.nenner);
	}
	
	Rational subt (Rational r){
		int newThisZaehler = this.zaehler * r.nenner;
		int newRZaehler = r.zaehler * this.nenner; 
		return new Rational(newThisZaehler - newRZaehler, this.nenner * r.nenner);
	}
	
	Rational mult (Rational r){
		return new Rational(this.zaehler * r.zaehler, this.nenner * r.nenner);
	}
	
	Rational div (Rational r){
		return new Rational(this.zaehler * r.nenner, this.nenner * r.zaehler);
	}
	
	void kuerze(){
		int ggT;
		ggT = ggT(this.zaehler,this.nenner);
		this.zaehler = this.zaehler/ggT;
		this.nenner = this.nenner/ggT;
	}//kuerze
		
	static int ggT(int a, int b) { 
		while(a != b){
			if (a > b)	a -= b;
			else 		b -= a;
		}
		return a;
    }//Berechnet den ggT zweier Zahlen
	
}//Rational
	
class RationalTest{
	
	public static void main(String [] args){
			Scanner in = new Scanner(System.in);		
			int auswahl=0;
			int zaehler;
			int zaehler2;
			int nenner;
			int nenner2;
			int zaehlerneu;
			String fertig;
		do{
			System.out.println("Bitte waehlen Sie aus:");
			System.out.println("1 - addieren ");
			System.out.println("2 - subtrahieren ");
			System.out.println("3 - multiplizieren ");
			System.out.println("4 - dividieren ");
			auswahl = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der ersten Zahl ein: ");
			zaehler = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der ersten Zahl ein: ");
			nenner = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der zweiten Zahl ein: ");
			zaehler2 = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
			nenner2 = in.nextInt();
			Rational r1 = new Rational(zaehler, nenner);		
			Rational r2 = new Rational(zaehler2, nenner2);
			Rational ergebnis = r1.sum(r2);
			
			switch(auswahl){
				case 1: ergebnis = r1.sum(r2);	break;
				case 2:	ergebnis = r1.subt(r2);	break;
				case 3: ergebnis = r1.mult(r2);	break;
				case 4:	ergebnis = r1.div(r2);	break;
			}//switch
			ergebnis.kuerze();
			System.out.println("Das ergebnis lautet:"+ ergebnis);
			System.out.println("Moechten sie eine weitere Berechnung durchfuehren?(1=ja,0=nein): ");
			auswahl = in.nextInt();
			
		}//do
		while(auswahl == 1);
		
	}//main
	
}//RationalTest
 
W

Wishmaster51

Gast
Habs echt soweit geschafft... Wenn du mir jetzt noch einmal erklärst, warum ich hier ein default brauche, um kuerze() nicht verhungern zu lassen und warum toString automatisch ausgeführt wird, wär ich dir ein weiteres Mal dankbar!
Weil du sonst eine NullPointerException bekommst.

Du musst, nachdem du die main-Methode ausgeführt hast, den Stream mit
Code:
in.close();
schließen. Schau dir mal die Domumentaion dazu an.
 

AquaBall

Top Contributor
Wenn du mir jetzt noch einmal erklärst, warum ich hier ein default brauche, um kuerze() nicht verhungern zu lassen und warum toString automatisch ausgeführt wird, wär ich dir ein weiteres Mal dankbar!

[JAVA=87] Rational ergebnis = r1.sum(r2);

switch(auswahl){
case 1: ergebnis = r1.sum(r2); break;
case 2: ergebnis = r1.subt(r2); break;
case 3: ergebnis = r1.mult(r2); break;
case 4: ergebnis = r1.div(r2); break;
}//switch
ergebnis.kuerze();
[/code]

... weil du nicht brauchst:
[JAVA=87] Rational ergebnis = r1.sum(r2); // nicht falsch, aber sinnlos und unnötig.
[/code]
sondern:
[JAVA=87] Rational ergebnis;
[/code]

Dann könnte theoretisch (jemand gibt 'Punkt 5' ein)
Code:
ergebnis
undefiniert sein:
[JAVA=87] ergebnis.kuerze(); // Päng! (Zur Laufzeit,)
[/code]
(Auch wenn du das abfangst, [was übrigens sein sollte] weiß der Compiler nicht, dass
Code:
ergebnis != null
gesichert ist, und meckert zur CompileZeit)

Außerdem: ein default ist fast immer sauberer Praxis und zumindest dokumentarisch sehr vorteilhaft.
Man erkennt, dass der Programmierer mitgedacht hat, und nichts übersehen wurde:
Java:
            switch(...){
                case ...
                default: //unmöglich, wurde bei ... überprüft.
            }//switch

toString ist die StandardMethode, die automatisch angewendet wird, wenn du ein Objekt offensichtlich als String verwenden willst. (Deshalb heißt sie so :D).
println erwartet einen String als Parameter, deshalb kannst du dir hier das
Code:
.toString()
sparen.
(... und verblüfft das viele Anfänger, dass hier Typ@HashCode kommt, wenn stoString nicht überschrieben wurde.)
 
Zuletzt bearbeitet:
Hallo nochmal,

was ich gänzlich vergessen hatte ist, eine eigene exception anzulegen, um einen korrekten Aufruf von meinen Konstruktor Rational zu gewährleisten. Ich frage mich jetzt grade, an welcher Stelle ich die Exception auslösen/werfen soll.

Nochmal genau zur Aufgabenstellung:

Rational(int z, int n)throws IllegalArgumentException

Der parametrisierte Konstruktor soll die Attribute der Klasse Rational mit den übergebenen
Werten initialisieren. Wenn der Konstruktor in einer Weise benutzt wird, der den obigen
Bedingungen widerspricht, soll eine Exception ausgelöst werden und an die aufrufende Methode
weitergereicht und dort behandelt werden.


Die aufrufende Methode ist doch in diesem Falle das Benutzen des Konstruktors, oder nicht?
Ich habe meine exception negativerNenner genannt. Das wäre z.B. eine Eingabe, die nicht gemacht werden dürfte. Ich habe probiert die exception im Konstruktor zu werfen, aber geht das überhaupt? Für mich hat das dort vom Verständnis her nichts zu suchen. Oder darf eine exception überall gewrofen werden? Außerdem wird durch den try Block in Zeile 105, in der main, wieder verhindert, dass überhaupt Objekte angelegt werden können. Somit habe ich wieder endlos viele compilierfehler. Aber genau diese Stelle muss ich doch überprüfen, um zu wissen ob ein Objekt mit den richtigen Werten angelegt wurde.

grüße

Simon

Java:
import java.util.*;

class negativerNenner extends Exception {		//eigens erstellte Exception
	
	String s;
	int w;
	
	negativerNenner(String text, int wert) {    //Konstruktor für die Exception
	
	this.s = text;
	this.w = wert;
	}
	
public String toString() {
	return "Fehler : negativer Nenner [" + s + w + "] ";
}

}//Exception
	
class Rational{

	private int zaehler;
	private int nenner;
	
	public Rational() {								
		zaehler = 0;
		nenner = 1;
	}//parameterloser Konstruktor zum initialiesieren des rationalen wertes null
	
	public Rational(int z, int n)throws negativerNenner {
		zaehler = z;
		nenner = n;
		if(nenner<0) throw new negativerNenner("Negativer Eingabewert fuer n = ", n);
	}//parametrisierter Konstruktor zum initialisieren einer rationalen Zahl mit den Werten für Zähler und Nenner
	
	public String toString() {
		return this.zaehler + "/" + this.nenner;
	}//Methode, die toString überschreibt und einen String mit dem Bruch erzeugt
	
	Rational sum (Rational r) {
		int newThisZaehler = this.zaehler * r.nenner;									
		int newRZaehler = r.zaehler * this.nenner;	
		return new Rational(newThisZaehler + newRZaehler, this.nenner * r.nenner);
	}//Methode addiert zwei rationale Zahlen
	
	Rational subt (Rational r) {
		int newThisZaehler = this.zaehler * r.nenner;
		int newRZaehler = r.zaehler * this.nenner; 
		return new Rational(newThisZaehler - newRZaehler, this.nenner * r.nenner);
	}//Methode subtrahiert zwei rationale Zahlen
	
	Rational mult (Rational r) {
		return new Rational(this.zaehler * r.zaehler, this.nenner * r.nenner);
	}//Methode multipliziert zwei rationale Zahlen
	
	Rational div (Rational r) {
		return new Rational(this.zaehler * r.nenner, this.nenner * r.zaehler);
	}////Methode dividiert zwei rationale Zahlen
	
	void kuerze() {
		int ggT;
		ggT = ggT(this.zaehler,this.nenner);			//Zum kürzen wird der ggT des Zahlers und Nenner per Methodenaufruf bestimmt
		this.zaehler = this.zaehler/ggT;				//Jetzt werden z und n durch eben diesen ggT geteilt
		this.nenner = this.nenner/ggT;
	}//kuerze
		
	static int ggT(int a, int b) { 					
		if(a<0) a= -a;
		while(a != b){
			if (a > b)	a -= b;
			else 		b -= a;
		}
		return a;
    }//Berechnet den ggT zweier Zahlen
	
}//Rational
	
class RationalTest {
	
	public static void main(String [] args) {			
			Scanner in = new Scanner(System.in);		
			int auswahl=0;
			int zaehler;
			int zaehler2;
			int nenner;
			int nenner2;
			int zaehlerneu;
			String fertig;
		do{
			System.out.println("Bitte waehlen Sie aus:");
			System.out.println("1 - addieren ");
			System.out.println("2 - subtrahieren ");
			System.out.println("3 - multiplizieren ");
			System.out.println("4 - dividieren ");
			auswahl = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der ersten Zahl ein: ");
			zaehler = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der ersten Zahl ein: ");
			nenner = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der zweiten Zahl ein: ");
			zaehler2 = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
			nenner2 = in.nextInt();
			Rational ergebnis = r1.sum(r2);
			try{
				Rational r1 = new Rational(zaehler, nenner);
				Rational r2 = new Rational(zaehler2, nenner2);
				}
			catch(negativerNenner e){
				System.out.println(e.toString()); 
				auswahl = 5;                                                          //Schickt den switch auf default
			}
				
			switch(auswahl) {								
				case 1: ergebnis = r1.sum(r2);				//Aufruf der Methode ergebnis auf dem Objekt r1, dadruch werden die Attribute von r1 mit this angesprochen
						System.out.print(r1);
						System.out.print(" + ");
						System.out.print(r2);
						System.out.print(" = ");
						System.out.print(ergebnis);
						System.out.print(" = ");
						break;
				
				case 2:	ergebnis = r1.subt(r2);
						System.out.print(r1);
						System.out.print(" - ");
						System.out.print(r2);
						System.out.print(" = ");
						System.out.print(ergebnis);
						System.out.print(" = ");
						break;
				case 3: ergebnis = r1.mult(r2);
						System.out.print(r1);
						System.out.print(" * ");
						System.out.print(r2);
						System.out.print(" = ");
						System.out.print(ergebnis);
						System.out.print(" = ");
						break;
				case 4:	ergebnis = r1.div(r2);
						System.out.print(r1);
						System.out.print(" : ");
						System.out.print(r2);
						System.out.print(" = ");
						System.out.print(ergebnis);
						System.out.print(" = ");
						break;
						
				default : break;
			}//switch
			ergebnis.kuerze();							
			System.out.println(ergebnis);
			System.out.println("Moechten sie eine weitere Berechnung durchfuehren?(1=ja,0=nein): ");
			auswahl = in.nextInt();
			
		}//do
		while(auswahl == 1);
		
	}//main
	
}//RationalTest
 

HimBromBeere

Top Contributor
Klar kannst du eine Exception überall werfen, da jede Programmzeile schließlich auch einen Fhler verursachen kann. Aber die toString-Methode der Exception brauchst du nicht zu überschreiben. Üblicherweise wirst du lediglich einen Konstruktor mit der Fehlermeldung erstellen, das war´s bereits:
Java:
public class NegativerNenner extends Exception {

	
	public NegativerNenner() {}
	public NegativerNenner(String msg) {super(msg);}
}

In deinem Fall brauchst du aber nichtmal eine eigene Exception zu bauen, denn die Aufgaabe sagt ja bereits, dass es eine IllegalArgumentException sein soll. Schreib also einfach in den Konstruktor:
Java:
public Rational(int zaehler, int nenner) throws IllegalArgumentException {
    if (nenner <= 0) throw new IllegalArgumentException("Nenner muss größer als 0 sein (ist " + nenner + ")");
    this.zaehler = zaehler;
    this.nenner = nenner;
}
 
Zuletzt bearbeitet:

AquaBall

Top Contributor
Außerdem wird durch den try Block in Zeile 105, in der main, wieder verhindert, dass überhaupt Objekte angelegt werden können.

Nicht durch den Try wird das verhindert, der arbeitet regulär.
Aber durch deine '{' machst du (nowendigerweise) einen Block, und nur in dem is r2 (lokal).
Nachdem du die Klammern aber brauchst muss du die Variablen außerhalb definieren.

PS: Du bist ein Fan von Mehrzeilern, nicht wahr?

[JAVA=100] ...
System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
nenner2 = in.nextInt();
Rational ergebnis = r1.sum(r2);
Rational r1;
Rational r2;
try{
r1 = new Rational(zaehler, nenner);
r2 = new Rational(zaehler2, nenner2);
}
catch(negativerNenner e){
System.out.println(e.toString());
auswahl = 5; //Schickt den switch auf default
}

switch(auswahl) {
case 1: ergebnis = r1.sum(r2); //Aufruf der Methode ergebnis auf dem Objekt r1, dadruch werden die Attribute von r1 mit this angesprochen
System.out.print(r1+ " + " + r2 + " = " + ergebnis + " = ");
// SO gehts auch.
break;

case 2: ergebnis = r1.subt(r2);
System.out.print(r1+ " - " + r2 + " = " + ergebnis + " = ");
break;
...[/code]
 
Warum klappt das nicht? Ich habe schon soviel rumgebastelt, er sagt mir für diesen Fall, dass r1 und r2 nicht initialisiert werden!? Ich verstehs nicht.

Java:
...
			Rational r1;
			Rational r2;
			Rational ergebnis = r1.sum(r2);
			
			try{
				 r1 = new Rational(zaehler, nenner);
				 r2 = new Rational(zaehler2, nenner2);
				}
			catch(IllegalArgumentException e){
				auswahl = 5;
			}
...
 
B

bone2

Gast
weil r1 und r2 zum zeitpunkt
Code:
Rational ergebnis = r1.sum(r2);
ganz offensichtlich nicht initialisiert sind. stehen stehen doch eine zeile drüber o_O

mach da draus:
Code:
Rational ergebnis;
 

AquaBall

Top Contributor
Warum klappt das nicht? Ich habe schon soviel rumgebastelt, er sagt mir für diesen Fall, dass r1 und r2 nicht initialisiert werden!? Ich verstehs nicht.

Java:
...
			Rational r1;
			Rational r2;
			Rational ergebnis = r1.sum(r2);
...


Jetzt wurde dir schon mehrfach gesagt, dass dein
Code:
Rational ergebnis = r1.sum(r2);
sinnlos ist!
(siehe auch http://www.java-forum.org/java-basics-anfaenger-themen/138063-rational-2.html#post913637) da du den Wert weder verwendest, noch brauchst, und später erst weißt welche Operation du haben willst!

Wenn du um Hilfe bittest, dann musst du die Posts auch durchlesen, und einarbeiten!

Und setz dich etwas mehr mit Variable / Definition / Instanziierung / Initialisierung auseinander!
 
Zuletzt bearbeitet:
Jetzt wurde dir schon mehrfach gesagt, dass dein Rational ergebnis = r1.sum(r2); sinnlos ist!
Das habe ich bis hierhin gemacht, weil ich das Programm sonst einfach nicht copmpilieren konnte!

Der Fehler liegt doch zurzeit daran, dass ich keine Objekt ergebnis erzeuge oder? Wie gesagt, hab alles was mir einfiel versucht.

Java:
import java.util.*;

class Rational{

	private int zaehler;
	private int nenner;
	
	public Rational() {								
		zaehler = 0;
		nenner = 1;
	}//parameterloser Konstruktor zum initialiesieren des rationalen wertes null
	
	public Rational(int z, int n)throws IllegalArgumentException {
		zaehler = z;
		nenner = n;
		if(nenner<0) throw new IllegalArgumentException("Der Nenner muss größer Null sein!");
	}//parametrisierter Konstruktor zum initialisieren einer rationalen Zahl mit den Werten für Zähler und Nenner
	
	public String toString() {
		return this.zaehler + "/" + this.nenner;
	}//Methode, die toString überschreibt und einen String mit dem Bruch erzeugt
	
	Rational sum (Rational r) {
		int newThisZaehler = this.zaehler * r.nenner;									
		int newRZaehler = r.zaehler * this.nenner;	
		return new Rational(newThisZaehler + newRZaehler, this.nenner * r.nenner);
	}//Methode addiert zwei rationale Zahlen
	
	Rational subt (Rational r) {
		int newThisZaehler = this.zaehler * r.nenner;
		int newRZaehler = r.zaehler * this.nenner; 
		return new Rational(newThisZaehler - newRZaehler, this.nenner * r.nenner);
	}//Methode subtrahiert zwei rationale Zahlen
	
	Rational mult (Rational r) {
		return new Rational(this.zaehler * r.zaehler, this.nenner * r.nenner);
	}//Methode multipliziert zwei rationale Zahlen
	
	Rational div (Rational r) {
		return new Rational(this.zaehler * r.nenner, this.nenner * r.zaehler);
	}////Methode dividiert zwei rationale Zahlen
	
	void kuerze() {
		int ggT;
		ggT = ggT(this.zaehler,this.nenner);			//Zum kürzen wird der ggT des Zahlers und Nenner per Methodenaufruf bestimmt
		this.zaehler = this.zaehler/ggT;				//Jetzt werden z und n durch eben diesen ggT geteilt
		this.nenner = this.nenner/ggT;
	}//kuerze
		
	static int ggT(int a, int b) { 					
		if(a<0) a= -a;
		while(a != b){
			if (a > b)	a -= b;
			else 		b -= a;
		}
		return a;
    }//Berechnet den ggT zweier Zahlen
	
}//Rational
	
class RationalTest {
	
	public static void main(String [] args) {			
			Scanner in = new Scanner(System.in);		
			int auswahl=0;
			int zaehler;
			int zaehler2;
			int nenner;
			int nenner2;
			int zaehlerneu;
			String fertig;
		do{
			System.out.println("Bitte waehlen Sie aus:");
			System.out.println("1 - addieren ");
			System.out.println("2 - subtrahieren ");
			System.out.println("3 - multiplizieren ");
			System.out.println("4 - dividieren ");
			auswahl = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der ersten Zahl ein: ");
			zaehler = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der ersten Zahl ein: ");
			nenner = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der zweiten Zahl ein: ");
			zaehler2 = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
			nenner2 = in.nextInt();
			Rational r1;
			Rational r2;
			Rational ergebnis;
			
			try{
				 r1 = new Rational(zaehler, nenner);
				 r2 = new Rational(zaehler2, nenner2);
				}
			catch(IllegalArgumentException e){
				auswahl = 5;
			}
				
			switch(auswahl) {								
				case 1: ergebnis = r1.sum(r2);				//Aufruf der Methode ergebnis auf dem Objekt r1, dadruch werden die Attribute von r1 mit this angesprochen
						System.out.print(r1+ " + " + r2 + " = " + ergebnis + " = ");
						break;
				case 2:	ergebnis = r1.subt(r2);
						System.out.print(r1+ " - " + r2 + " = " + ergebnis + " = ");
						break;
				case 3: ergebnis = r1.mult(r2);
						System.out.print(r1+ " * " + r2 + " = " + ergebnis + " = ");
						break;
				case 4:	ergebnis = r1.div(r2);
						System.out.print(r1+ " : " + r2 + " = " + ergebnis + " = ");
						break;
						
				default : break;
			}//switch
			ergebnis.kuerze();							
			System.out.println(ergebnis);
			System.out.println("Moechten sie eine weitere Berechnung durchfuehren?(1=ja,0=nein): ");
			auswahl = in.nextInt();
			
		}//do
		while(auswahl == 1);
		
	}//main
	
}//RationalTest
 
Zuletzt bearbeitet:

AquaBall

Top Contributor
Welchen Fehler hast du jetzt noch?
Du hast vermutlich nur noch die Warnung dass Ergebnis unbelegt sein kann.
(Hab ich in meinem ersten Post zuwenig darauf hingewiesen?)

Das führt (erst seit du Wert 5 im try eingeführt hast!) bei Fehleingaben (Negativer Nenner) zum besagten Päng mit
Code:
ergebnis.kuerze();
!

Ich würde auch die Variablen natürlich an 1 Stelle zusammenfassen.
Java:
public static void main(String [] args) {           
        int auswahl=0;
        int zaehler, zaehler2, nenner, nenner2, zaehlerneu;
        String fertig;
        Rational r1, r2, ergebnis = new Rational();
        Scanner in = new Scanner(System.in);        
        do{
            System.out.println("Bitte waehlen Sie aus:");
...


PS: Und weil wir gerade dabei sind:

1) Das ist eine sehr gefährliche Begründung!
... dein Rational ergebnis = r1.sum(r2); sinnlos ist!
Das habe ich bis hierhin gemacht, weil ich das Programm sonst einfach nicht copmpilieren konnte!
Wenn etwas nicht kompiliert, dann hast du nen Fehler! Also beheb diesen statt vertuschen!
Mit Symptombekämpfung kommst du nicht weiter (wie sich nun herausstellt) und lernst du nicht dazu.
Zum Glück musst du bei Compilerfehlern die Fehler nur von oben der Reihe nach abarbeiten.
Bei Logikfehlern kann der Fehler ganz woanders stecken.


2) Ich hab deine Ausgabe immer hingenommen, abr warum schreibst du
Java:
System.out.print(r1+ " + " + r2 + " = " + ergebnis + " = ");
Wäre nicht angebrachter:
Java:
System.out.println(r1+ " + " + r2 + " = " + ergebnis + ". ");

3) Als ProgrammEnde wäre etwas eleganter:
Java:
            System.out.println("Moechten sie eine weitere Berechnung durchfuehren? (j/n): ");
            String weiter = in.next();
        }//do
        while(weiter.equals("j"));
 
Zuletzt bearbeitet:
Du hast ja recht. Ich habs mir zu bequem gemacht, wobei ich mir zwischendurch auch dachte, was diese Zeile überhaupt für einen Sinn hat. Beim rausnehmen hab ich es dann sozusagen gemerkt, aber nicht verstanden.

Ich bekomme immer noch die Meldung: "Variable r1 might not have been initialized",in Zeile 95. Dasselbe für r2 und ergebnis.

Nur nochmal zum Verständnis:

Zeile 69. Was genau macht die? Weil erzeugt werden die Objekte erst später. Wird hier schonmal eine Speicheradresse gesichert? Ich meine r1,r2 werden ja dann auch im catch block erzeugt, aber ergebnis z.B. nicht. Trotzdem könnte ich ergebnis dann mit dem Funktionsaufruf beschreiben? Oh man...

Java:
import java.util.*;

class Rational{

	private int zaehler;
	private int nenner;
	
	public Rational() {								
		zaehler = 0;
		nenner = 1;
	}//parameterloser Konstruktor zum initialiesieren des rationalen wertes null
	
	public Rational(int z, int n)throws IllegalArgumentException {
		zaehler = z;
		nenner = n;
		if(nenner<0) throw new IllegalArgumentException("Der Nenner muss größer Null sein!");
	}//parametrisierter Konstruktor zum initialisieren einer rationalen Zahl mit den Werten für Zähler und Nenner
	
	public String toString() {
		return this.zaehler + "/" + this.nenner;
	}//Methode, die toString überschreibt und einen String mit dem Bruch erzeugt
	
	Rational sum (Rational r) {
		int newThisZaehler = this.zaehler * r.nenner;									
		int newRZaehler = r.zaehler * this.nenner;	
		return new Rational(newThisZaehler + newRZaehler, this.nenner * r.nenner);
	}//Methode addiert zwei rationale Zahlen
	
	Rational subt (Rational r) {
		int newThisZaehler = this.zaehler * r.nenner;
		int newRZaehler = r.zaehler * this.nenner; 
		return new Rational(newThisZaehler - newRZaehler, this.nenner * r.nenner);
	}//Methode subtrahiert zwei rationale Zahlen
	
	Rational mult (Rational r) {
		return new Rational(this.zaehler * r.zaehler, this.nenner * r.nenner);
	}//Methode multipliziert zwei rationale Zahlen
	
	Rational div (Rational r) {
		return new Rational(this.zaehler * r.nenner, this.nenner * r.zaehler);
	}////Methode dividiert zwei rationale Zahlen
	
	void kuerze() {
		int ggT;
		ggT = ggT(this.zaehler,this.nenner);			//Zum kürzen wird der ggT des Zahlers und Nenner per Methodenaufruf bestimmt
		this.zaehler = this.zaehler/ggT;				//Jetzt werden z und n durch eben diesen ggT geteilt
		this.nenner = this.nenner/ggT;
	}//kuerze
		
	static int ggT(int a, int b) { 					
		if(a<0) a= -a;
		while(a != b){
			if (a > b)	a -= b;
			else 		b -= a;
		}
		return a;
    }//Berechnet den ggT zweier Zahlen
	
}//Rational
	
class RationalTest {
	
	public static void main(String [] args) {			
			Scanner in = new Scanner(System.in);		
			int auswahl=0;
			int zaehler, zaehler2, nenner, nenner2, zaehlerneu;
			String fertig,nochmal;
			Rational r1, r2, ergebnis;
		do{
			System.out.println("Bitte waehlen Sie aus:");
			System.out.println("1 - addieren ");
			System.out.println("2 - subtrahieren ");
			System.out.println("3 - multiplizieren ");
			System.out.println("4 - dividieren ");
			auswahl = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der ersten Zahl ein: ");
			zaehler = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der ersten Zahl ein: ");
			nenner = in.nextInt();
			System.out.println("Bitte geben Sie den Zaehler der zweiten Zahl ein: ");
			zaehler2 = in.nextInt();
			System.out.println("Bitte geben Sie den Nenner der zweiten Zahl ein: ");
			nenner2 = in.nextInt();
			
			try{
				 r1 = new Rational(zaehler, nenner);
				 r2 = new Rational(zaehler2, nenner2);
				}
			catch(IllegalArgumentException e){
				auswahl = 5;
			}
				
			switch(auswahl) {								
				case 1: ergebnis = r1.sum(r2);				//Aufruf der Methode ergebnis auf dem Objekt r1, dadruch werden die Attribute von r1 mit this angesprochen
						System.out.print(r1+ " + " + r2 + " = " + ergebnis + " = ");
						break;
				case 2:	ergebnis = r1.subt(r2);
						System.out.print(r1+ " - " + r2 + " = " + ergebnis + " = ");
						break;
				case 3: ergebnis = r1.mult(r2);
						System.out.print(r1+ " * " + r2 + " = " + ergebnis + " = ");
						break;
				case 4:	ergebnis = r1.div(r2);
						System.out.print(r1+ " : " + r2 + " = " + ergebnis + " = ");
						break;
						
				default : break;
			}//switch
			ergebnis.kuerze();							
			System.out.println(ergebnis);
			System.out.println("Moechten sie eine weitere Berechnung durchfuehren?(j,n): ");
			nochmal = in.next();
			
		}//do
		while(nochmal.equals("j"));
		
	}//main
	
}//RationalTest
 
Zuletzt bearbeitet:

AquaBall

Top Contributor
Crash-Kurs:

Klasse definieren: Der Compiler weiß, wie Eigenschaften und Methoden funktionieren sollen.
Java:
class Rational {
...
}
Variable definieren und instanziieren: Der Compiler weiß, dass dieses Symbol für ein
Code:
Rational
gilt. Er stellt 1 (EINE) Speicheradresse zur Verfügung. (Weiß aber noch nicht wohin er zeigen soll, deshalb steht dort
Code:
null
)
[JAVA=69]Rational r1;
[/code]

Variable initialisieren: Der Compiler stellt den benötigten Platz zur Verfügung und merkt sich diesen Platz in der Speicheradresse (die Null ist nun überschreiben). Dabei wird der entsprechende
Code:
Konstruktor
verwendet.
[JAVA=69]r1 = new Rational();
[/code]

Variable verwenden: Der Compiler holt (über Getter/...) aus dem Speicherplatz auf den von Adresse hingezeigt wird die entsprechenden Werte.
Java:
z=r1.zaehler:

Wenn nun r2 nicht initialisiert wurde, denn zeigt r1 auf null, und dort gibts aber keine Werte. ->Päng!

Da das passieren kann, wenn z.b. r1 ungültig eingegeben wird, dann würde jede Berechnung von Ergebnis
Code:
ergebnis = r1.sum(r2)
mit einem leeren r2 (=null) konfrontiert sein.
Das meldet der Compiler, auch wenn es zur Laufzeit nicht immer ein Problem geben muss.


mit:
Java:
Rational r1, r2, ergebnis = new Rational();
(Was du übrigens nicht so genommen hast wie ich im letzten Post angegeben habe)
wäre r1 und r2 instanziiert, aber nur ergebnis initialisiert.
Das sollte reichen, obwohl der Compiler noch eine Warnung ausdgeben dürfte.

Alles erledigen kannst du mit:
Java:
Rational r1 = new Rational(), r2 = new Rational(), ergebnis = new Rational();

PS: Ich hab gehört, dass darüber schon Bücher geschrieben worden sein sollen!
 
Zuletzt bearbeitet:

Crian

Top Contributor
Ein paar Randbemerkungen: Die Kommentare am Ende der Methoden sind ungewöhnlich.

1) Wenn du statt

Java:
    Rational subt (Rational r) {
        int newThisZaehler = this.zaehler * r.nenner;
        int newRZaehler = r.zaehler * this.nenner; 
        return new Rational(newThisZaehler - newRZaehler, this.nenner * r.nenner);
    }//Methode subtrahiert zwei rationale Zahlen

Java:
    /** Methode subtrahiert zwei rationale Zahlen. */
    Rational subt (Rational r) {
        int newThisZaehler = this.zaehler * r.nenner;
        int newRZaehler = r.zaehler * this.nenner; 
        return new Rational(newThisZaehler - newRZaehler, this.nenner * r.nenner);
    }


oder noch korrekter

Java:
    /**
     *  Die Methode subtrahiert die übergebene rationale Zahl von dieser.
     *
     * @param r Von dieser Zahl zu subtrahierende Zahl.
     */
    Rational subt (Rational r) {
        int newThisZaehler = this.zaehler * r.nenner;
        int newRZaehler = r.zaehler * this.nenner; 
        return new Rational(newThisZaehler - newRZaehler, this.nenner * r.nenner);
    }

schreibst, dann wird in Eclipse zum Beispiel beim überfahren irgendeines [c]xxx.subt(r)[/c] diese Erklärung angezeigt. Sehr hilfreich.

2) Sprechende Variablennamen sind vorteilhaft. [c]r[/c] kann alles mögliche sein.

3) Sprechende Methodennamen sind auch wichtig. Ich weiß, diese sind hier so vorgegeben. Trotzdem hässlich. Auch dass es "sum" und nicht "add" heißt.

4) In einer Zeile sollte nicht zu viel passieren.

Java:
int zaehler, zaehler2, nenner, nenner2, zaehlerneu;

finde ich hässlich.

5) Der oben gegebene Rat Dinge zusammen zu fassen ist zweischneidig.

Natürlich kannst du statt
Java:
    Rational mult (Rational r){
        int newNenner = this.nenner * r.nenner;
        int newZaehler = this.zaehler * r.zaehler;
        return new Rational(newZaehler, newNenner);
    }

Java:
    Rational mult (Rational r){
        return new Rational(this.zaehler * r.zaehler, this.nenner * r.nenner);
    }

schreiben. Aber die Methode ist kurz und übersichtlich. Wenn du nach längerer Zeit mal rein schaust, ist obiges deutlich klarer, die temporären Variablen optimiert Java eh weg. Damit kann man aber Dinge im Code zum Ausdruck bringen.

Außerdem wirst du dankbar sein, wenn du mal durch den Code debuggst und an solchen Stellen Zwischenergebnisse direkt ablesen kannst.

Wie du siehst ist das aber Geschmackssache.

6)
Code:
toString()

Java:
public String toString(){
    return this.zaehler + "/" + this.nenner;
}

Sauberer ist

Java:
public String toString(){
    return Integers.toString(zaehler) + "/" + Integers.toString(nenner);
}
 
Zuletzt bearbeitet:
B

buzz!dev

Gast
Den letzten Punkt mit toString verstehe ich nicht. Wieso sollte die zweite Variante "sauberer" sein? Bei
Code:
zaehler + "/" + nenner
wird aus dem ganzen doch automatisch ein String - wieso also so verkomplizieren?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B JUnit Test Klasse Rational Java Basics - Anfänger-Themen 12

Ähnliche Java Themen

Neue Themen


Oben