Brüche kürzen

Hallo werte Forumsmitglieder,

das ist meiner erster Forumsbeitrag, also entschuldige ich mich im Vorhinein für irgendwelche Fehler, die ich machen könnte.

Ich möchte ein Programm schreiben, womit Brüche repräsentiert und damit gerechnet werden können. Darin habe ich einmal die shorten()-Methode, womit alle Brüche nach dem Berechnen gekürzt werden:

Java:
    public void shorten() {
        int factorC = GCD(numerator, denominator);
        numerator = numerator/factorC;
        denominator = denominator/factorC;
    }

Außerdem habe ich mehrere Methoden geschrieben, womit man verschiedene Rechenoperationen durchführen kann, z.B. hier Addition und Division:

Code:
    public Fraction add(Fraction f) {
        numerator = numerator * f.denominator + f.numerator * denominator;
        denominator = denominator * f.denominator;
        sum = new Fraction(numerator * denominator);
        return sum;
    }

public Fraction divide(Fraction f) {
numerator = numerator * f.denominator;
denominator = denominator * f.numerator;
quotient = new Fraction(numerator, denominator);
return quotient;
}

Dabei möchte ich, dass am Ende der Operations-Methoden die Brüche gekürzt werden. Daher sollte ich bei dieser Methode z.B einen neuen Bruch erstellen (new Fraction) und dann auf diesem shorten() aufrufen (es ist ja eine Objektmethode) und diesen dann mit return zurückgeben. Ich weiß aber nicht, wie ich es machen soll. Kann mir jemand anhand meines Quelltextes zeigen?
 

mihe7

Top Contributor
Nein, in einem Konstruktor der Klasse Fraction, versteht sich. Da Du ja neue Fraction-Objekte zurückgibst, würde dann automatisch gekürzt.
 
Nein, die Köpfe der geforderten Methoden in meiner Aufgabe sind bereits vorgegeben und dürfen nicht verändert werden. Der Quelltext, der in der Aufgabe vorgegeben und teilweise von mir bearbeitet wurde, sieht so aus:

Java:
public class Fraction {

    private int numerator, denominator;
    
    /**
     * Gibt den größten gemeinsamen Teiler der beiden Argumente (Greatest Common Divider) zurück.
     */
    public static int GCD(int x, int y) {
        if (y == 0) return x;
        return GCD(y, x % y);
    }

    /**
     * Gibt das kleinste gemeinsame Vielfache der beiden Argumente (Lowest Common Multiple) zurück.
     */
    public static int LCM(int x, int y) {
        return (x * y) / GCD(x, y);
    }
 //Beginn der Aufgabe 
   /**
     * Vollstaendig parametrisierter Konstruktor der Zaehler und Nenner
     * uebergeben bekommt und die entsprechenden Attribute setzt.
     * Negative Vorzeichen (Zahlen kleiner als Null) duerfen nur im Zaehler
     * auftreten (nicht im "denominator"-Attribut).
     * Die Uebergabe eines negativen Nenners ("denominator"-Argument) an den Konstruktor ist jedoch zulaessig.
     * Der Konstruktor muss also den uebergebenen Nenner pruefen und sein Vorzeichen so behandeln,
     * dass der resultierende Bruch (die Attribute) die genannte Restriktion erfüllt
     * und der Wert des Bruchs (die Argumente) unverändert bleibt
     * (ein negatives Vorzeichen im Nenner muss also methematisch korrekt beseitigt werden).
     * Wird eine Null als Nenner uebergeben, so wird das entsprechende Attribut
     * auf Eins gesetzt.
     * Jeder erzeugte Bruch wird gekuerzt (dazu soll die entsprechende Mehode s.u. verwendet werden).
     */
    public Fraction(int numerator, int denominator) {
        
        if(denominator<0){
            numerator = -numerator;
            denominator = -denominator;
        }
        if(denominator == 0){
            denominator = 1;
        }
        
    }

    /**
     * Gibt den Nenner zurueck.
     */
    public int getDenominator() {
        return denominator;
    }

    /**
     * Gibt den Zaehler zurueck.
     */
    public int getNumerator() {
        return numerator;
    }

    /**
     * Gibt den Bruch als Gleitkommazahl zurueck.
     */
    public double toDouble() {
        double fraction = (double)numerator / denominator;
        return fraction;
    }

    /**
     * Gibt einen String im Format
     * "Zaehler/Nenner" zurueck.
     */
    public String toString() {
        String fraction = numerator + "/" + denominator;
        return fraction;
    }

    /**
     * Kuerzt (vereinfacht) den Bruch.
     */
    public void shorten() {
        int factorC = GCD(numerator, denominator);
        numerator = numerator/factorC;
        denominator = denominator/factorC;
    }

    /**
     * Erweitert (macht gleichnamig), addiert dann den uebergebenen Bruch.
     */
    public Fraction add(Fraction f) {
        numerator = numerator * f.denominator + f.numerator * denominator;
        denominator = denominator * f.denominator;
        sum = new Fraction(numerator * denominator);
        return sum;
    }

    /**
     * Multipliziert mit dem uebergebenen Bruch.
     */
    public Fraction multiply(Fraction f) {
        numerator = numerator * f.numerator;
        denominator = denominator * f.denominator;
        shorten();
    }

    /**
     * Bildet den Kehrwert, wenn der Zaehler ungleich Null ist.
     * Sonst wird der Bruch unveraendert zurueckgegeben.
     */
    public Fraction reciprocal() {
               if(denominator<0){
            numerator = -numerator;
            denominator = -denominator;
        }
        if(denominator != 0){
            int newNumerator = numerator;
            int newDenominator = denominator;
            numerator = newDenominator;
            denominator = newNumerator;
            shorten();
        }
    }
    
    /**
     * Dividiert durch den uebergebenen Bruch
     * (unter Verwendung von Kehrwert und Multiplikation).
     */
    public Fraction divide(Fraction f) {
        numerator = numerator * f.denominator;
        denominator = denominator * f.numerator;
        quotient = new Fraction(numerator, denominator);
        return quotient;
    }
    
}

Die Kommentare sollen vorgeben, was gemacht werden soll.
 
Ich muss demnach die entsprechende Methode verwenden. Die ist ja shorten(). Ich habe ja versucht, diese Methode bei jeder Operation aufzurufen und zurückzugeben, hat aber nicht geklappt.
 

temi

Top Contributor
Ich muss demnach die entsprechende Methode verwenden. Die ist ja shorten(). Ich habe ja versucht, diese Methode bei jeder Operation aufzurufen und zurückzugeben, hat aber nicht geklappt.
Was hast du denn konkret versucht. Zeige doch einen kurzen Codeausschnitt!

Was @mihe7 sagte, war, dass du im Konstruktor die Methode zum Kürzen aufrufen sollst, d. h. sobald du einen neuen Bruch erzeugst, wird er auch gleich gekürzt.
 

KonradN

Super-Moderator
Mitarbeiter
Die Frage ist erst einmal: was heißt das „hat nicht geklappt“?

Das ist keine Aussage, mit der man was anfangen kann!

Mehrere Dinge fallen auf:
A) die Aufgabe verlangt in Zeile 32 etwas - mach das doch einfach!
B) die Signatur besagt doch, dass ein neuer Bruch zurück gegeben werden soll mit dem Ergebnis. Das impliziert für mich, dass die beteiligten Brüche nicht verändert werden. Du veränderst aber den Bruch.

Also wenn du hast c = a.add(b) dann soll das für c = a + b stehen und dabei werden a und b nicht verändert!
 
Die entsprechende Klasse, die laut Zeile 32 verwendet werden soll, um Brüche zu kürzen, ist shorten(), wenn ich mich nicht irre. Ich arbeite mal mit einem Abschnitt des Codes, nämlich der Addition der Brüche, die dann gekürzt werden sollen:

Java:
    public Fraction add(Fraction f) {
        numerator = numerator * f.denominator + f.numerator * denominator;
        denominator = denominator * f.denominator;
        sum = new Fraction(numerator * denominator);
        return sum;
    }

Laut Herrn KonradN habe ich den Bruch verändert. Meinen Sie damit sum? Soll ich es entfernen?

Oder soll ich es in einer Methode aufrufen, wie z.B:

Code:
Fraction sum = new Fraction();
 

KonradN

Super-Moderator
Mitarbeiter
Also erst einmal ist es wichtig, die Aufgabe zu verstehen. Und die erste Aufgabe findet sich direkt in der Beschreibung des Konstruktors:
* Jeder erzeugte Bruch wird gekuerzt (dazu soll die entsprechende Mehode s.u. verwendet werden).
Das ist die Zeile 32 bei dem Code, den Du gepostet hast und das ist der Hinweis, den Dir z.B. @mihe7 in #6 geben wollte.

Die anderen Punkt sind nicht so gut beschrieben (finde ich), aber es ist üblich, dass so Methoden entweder:
  • Den Status der Instanz, auf er sie aufgerufen wird, verändern (das wäre dann eine Methode wie: public void add (Fraction other) )
  • Die Instanz nicht verändert aber dafür ein Ergebnis zurück gibt. (Das wäre dann die Methode so wie bei Dir: public Fraction add (Fraction other) )
Mischversionen gibt es natürlich auch aber sind unüblich oder es wird der Rückgabewert auf etwas beschränkt wie ein Erfolg/Misserfolg.

Dein Code macht aber beides:
  • Erst veränderst Du den Status des Bruches selbst.
  • Dann erstellst Du eine Kopie des Bruches und gibst diesen zurück.

Also schauen wir einmal, was dies für Dich bedeutet:

1. Der Konstruktor soll auch den Bruch kürzen. Dazu kannst Du einfach die entsprechende Methode am Ende des Konstruktors aufrufen.

2. Du willst den neu erstellten Bruch kürzen. Wenn Du 1. gemacht hast, dann wird jeder Bruch automatisch gekürzt. Damit wäre dies nicht mehr notwendig. Aber wenn Du es manuell machen willst, dann kannst Du es natürlich auch machen:
Java:
quotient = new Fraction(numerator, denominator);
quotient.shorten();
return quotient;

3. Wenn Du den Bruch, auf dem die Methode aufgerufen werden soll, nicht verändern willst, dann würde es ausreichen, die Berechnung in neue lokale Variablen zu packen:


Code:
    public Fraction add(Fraction f) {
        int newNumerator = numerator * f.denominator + f.numerator * denominator;
        int newDenominator = denominator * f.denominator;
        Fraction sum = new Fraction(newNumerator * newDenominator);
        return sum;
    }

Was evtl. noch nicht gesagt wurde: Du musst Variablen erst Deklarieren, ehe du diese nutzen kannst. sum ist - so ich es nicht übersehen habe - noch nicht deklariert worden. Daher habe ich in dem Beispiel oben aus der reinen Zuweisung die Deklaration einer lokalen Variablen incl. Initialisierung gemacht. (Und in dem Codebeispiel habe ich kein shorten() aufgerufen - ich gehe davon aus, dass Du dies noch im Konstruktor machen wirst!
 

mihe7

Top Contributor
Ich muss demnach die entsprechende Methode verwenden. Die ist ja shorten().
Ja. Die Zeilen 20 bis 33 spezifizieren das Verhalten des Konstruktors und geben z. T. auch Implementierungshinweise (was man außerhalb von Aufgaben dort natürlich nicht finden würde).

Ich sehe Deine Aufgabe darin, dafür zu sorgen, dass der Konstruktor sich entsprechend verhält:
  1. Vollstaendig parametrisierter Konstruktor der Zaehler und Nenner uebergeben bekommt und die entsprechenden Attribute setzt.
  2. Negative Vorzeichen (Zahlen kleiner als Null) duerfen nur im Zaehler auftreten (nicht im "denominator"-Attribut). Die Uebergabe eines negativen Nenners ("denominator"-Argument) an den Konstruktor ist jedoch zulaessig. Der Konstruktor muss also den uebergebenen Nenner pruefen und sein Vorzeichen so behandeln, dass der resultierende Bruch (die Attribute) die genannte Restriktion erfüllt und der Wert des Bruchs (die Argumente) unverändert bleibt (ein negatives Vorzeichen im Nenner muss also methematisch korrekt beseitigt werden).
  3. Wird eine Null als Nenner uebergeben, so wird das entsprechende Attribut auf Eins gesetzt.
  4. Jeder erzeugte Bruch wird gekuerzt (dazu soll die entsprechende Mehode s.u. verwendet werden).
Dein Code:
Java:
    public Fraction(int numerator, int denominator) {
        
        if(denominator<0){
            numerator = -numerator;
            denominator = -denominator;
        }
        if(denominator == 0){
            denominator = 1;
        }
        
    }
macht von alledem nichts. Es setzt keine Attribute (Verstoß gegen 1) sondern ändert die Argumente (Verstoß gegen 2). Damit ist auch 3 hinfällig. Und auch 4 wird nicht umgesetzt, weil Du im Konstruktor eben shorten() nicht verwendest.
 

KonradN

Super-Moderator
Mitarbeiter
Wie kann ich das 1. machen? Denn als ich das 2. und 3. gemacht habe, hat meine Ausgabe z.B. quotient nicht erkennt.
Das Problem hier ist ja, dass die Parameter genau so heißen wie die Instanzvariablen. Damit werden die Instanzvariablen "versteckt".

Der Zugriff auf die Instanzvariablen kann über this erfolgen:
Java:
public class Test {
    private int zahl;
    
    public Test (int zahl) {
        // Parameter zahl versteckt Instanzvariable zahl
        // mit this.zahl kann man auf die Instanzvariable zugreifen:
        this.zahl = zahl;
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
Ach ja - das mit dem quotient hatte ich schon in meiner Antwort erklärt:

Wenn Du einer Variable (hier quotient) etwas zuweisen willst, musst Du die Variable erst deklarieren. Dazu kann man aus der reinen Zuweisung eine Deklaration einer lokalen Variable machen - inkl. Initialisierung.

Dies siehst Du in #12 als Beispiel mit der Variablen sum.
 
Okay,

vielen Dank erstmal Herr KonradN und Herr mihe7 für eure Ratschläge für add und quotient. Ich habe es so gemacht und es wurden dafür keine Fehler angezeigt.

Java:
    public Fraction add(Fraction f) {
        numerator = numerator * f.denominator + f.numerator * denominator;
        denominator = denominator * f.denominator;
        Fraction sum = new Fraction(numerator, denominator);
        sum.shorten();
        return sum;
    }

    public Fraction divide(Fraction f) {
        numerator = numerator * f.denominator;
        denominator = denominator * f.numerator;
        Fraction quotient = new Fraction(numerator, denominator);
        quotient.shorten();
        return quotient;
    }

Ich soll es ja alle Brüche kürzen, die ausgegeben werden sollen, also wie bei reciprocal() und multiply(Fraction f). Ich wollte fragen, ob das Kürzen laut Zeile 32 auch für die Methoden gilt, die über shorten() stehen? Und soll ich das gleiche wie bei add und divide auch bei reciprocal und multiply machen? Wenn ja, welche Namen soll ich verwenden? sum und quotient gehen dort glaube ich nicht.
 

mihe7

Top Contributor
Ich soll es ja alle Brüche kürzen, die ausgegeben werden sollen
Nein. Du sollst jeden erzeugten Bruch kürzen. Das erreichst Du, indem Du shorten im Konstruktor aufrufst und damit ist die Sache für jeden erzeugten Bruch erledigt.

Dann reicht z. B.:
Java:
    public Fraction multiply(Fraction f) {
        return new Fraction(numerator * f.numerator, denominator * f.denominator);
    }
weil der erzeugte Bruch automatisch gekürzt wurde.

EDIT: Code korrigiert.
 
Dann nicht für reciprocal, weil dort kein Parameter in den runden Klammern steht? => nicht gekürzt

Und ist meine Methode dafür in Ordnung? In der Ausgabe wird kein Fehler dazu angezeigt:

Java:
    public Fraction reciprocal() {
               if(denominator<0){
            numerator = -numerator;
            denominator = -denominator;
        }
        if(denominator != 0){
            int newNumerator = numerator;
            int newDenominator = denominator;
            numerator = newDenominator;
            denominator = newNumerator;
            shorten();
        }
    }
 

mihe7

Top Contributor
Deine Methoden ändern alle den aktuellen Bruch. Schreib die mal so um, dass der aktuelle Bruch nicht verändert wird, dann ergibt sich der Rest von alleine :)
 

KonradN

Super-Moderator
Mitarbeiter
Reicht es, es so zu schreiben? Oder fehlt etwas?

Java:
    public Fraction reciprocal() {
        return new Fraction(denominator,numerator);
    }
Hättest Du den Kommentar oberhalb der Methode nicht weggelöscht, dann könntest Du selbst schauen:

/**
* Bildet den Kehrwert, wenn der Zaehler ungleich Null ist.
* Sonst wird der Bruch unveraendert zurueckgegeben.
*/

Daher wäre die einfache Frage: Machst Du das, was da in der Doku beschrieben wurde?
 
Vielen Dank, dass Sie mich auf dem Kommentar hingewiesen haben. Ich habe Zähler und Nenner vertauscht und die Operationen für Vergleiche missachtet. Ist es jetzt besser? Und mir ist immer noch nicht klar, ob es gekürzt werden soll.

Java:
    public Fraction reciprocal() {
        if(numerator == 0){
            return new Fraction(numerator,denominator);
        }
        if(numerator != 0){
            return new Fraction(denominator,numerator);
        }
    }
 

KonradN

Super-Moderator
Mitarbeiter
Und wenn Du in dem if auf == 0 abfragst, dann kannst du den Fall, dass es nicht == 0 ist in einem else abbilden:
Java:
    public Fraction reciprocal() {
        if(numerator == 0) {
            return new Fraction(numerator,denominator);
        } else {
            return new Fraction(denominator,numerator);
        }
    }

Und da du ja auch mit return heraus gehst, brauchst du kein else. Es kann also einfach etwas sein wie:
Code:
    public Fraction reciprocal() {
        if(numerator == 0) return this;

        return new Fraction(denominator,numerator);
    }
 
Gibt es noch etwas, was ich in meinem Programm ändern soll? :

Java:
public class Fraction {

    private int numerator, denominator;
   
    /**
     * Gibt den größten gemeinsamen Teiler der beiden Argumente (Greatest Common Divider) zurück.
     */
    public static int GCD(int x, int y) {
        if (y == 0) return x;
        return GCD(y, x % y);
    }

    /**
     * Gibt das kleinste gemeinsame Vielfache der beiden Argumente (Lowest Common Multiple) zurück.
     */
    public static int LCM(int x, int y) {
        return (x * y) / GCD(x, y);
    }
 //Beginn der Aufgabe
   /**
     * Vollstaendig parametrisierter Konstruktor der Zaehler und Nenner
     * uebergeben bekommt und die entsprechenden Attribute setzt.
     * Negative Vorzeichen (Zahlen kleiner als Null) duerfen nur im Zaehler
     * auftreten (nicht im "denominator"-Attribut).
     * Die Uebergabe eines negativen Nenners ("denominator"-Argument) an den Konstruktor ist jedoch zulaessig.
     * Der Konstruktor muss also den uebergebenen Nenner pruefen und sein Vorzeichen so behandeln,
     * dass der resultierende Bruch (die Attribute) die genannte Restriktion erfüllt
     * und der Wert des Bruchs (die Argumente) unverändert bleibt
     * (ein negatives Vorzeichen im Nenner muss also methematisch korrekt beseitigt werden).
     * Wird eine Null als Nenner uebergeben, so wird das entsprechende Attribut
     * auf Eins gesetzt.
     * Jeder erzeugte Bruch wird gekuerzt (dazu soll die entsprechende Mehode s.u. verwendet werden).
     */
    public Fraction(int numerator, int denominator) {
       
        if(denominator<0){
            numerator = -numerator;
            denominator = -denominator;
        }
        if(denominator == 0){
            denominator = 1;
        }
       
    }

    /**
     * Gibt den Nenner zurueck.
     */
    public int getDenominator() {
        return denominator;
    }

    /**
     * Gibt den Zaehler zurueck.
     */
    public int getNumerator() {
        return numerator;
    }

    /**
     * Gibt den Bruch als Gleitkommazahl zurueck.
     */
    public double toDouble() {
        double fraction = (double)numerator / denominator;
        return fraction;
    }

    /**
     * Gibt einen String im Format
     * "Zaehler/Nenner" zurueck.
     */
    public String toString() {
        String fraction = numerator + "/" + denominator;
        return fraction;
    }

    /**
     * Kuerzt (vereinfacht) den Bruch.
     */
    public void shorten() {
        int factorC = GCD(numerator, denominator);
        numerator = numerator/factorC;
        denominator = denominator/factorC;
    }

    /**
     * Erweitert (macht gleichnamig), addiert dann den uebergebenen Bruch.
     */
    public Fraction add(Fraction f) {
        numerator = numerator * f.denominator + f.numerator * denominator;
        denominator = denominator * f.denominator;
        Fraction sum = new Fraction(numerator, denominator);
        sum.shorten();
        return sum;
    }

    /**
     * Multipliziert mit dem uebergebenen Bruch.
     */
    public Fraction multiply(Fraction f) {
        return new Fraction(numerator * f.numerator, denominator * f.denominator);
    }

    /**
     * Bildet den Kehrwert, wenn der Zaehler ungleich Null ist.
     * Sonst wird der Bruch unveraendert zurueckgegeben.
     */
    public Fraction reciprocal() {
        if(numerator == 0) return this;

        return new Fraction(denominator,numerator);
    }
   
    /**
     * Dividiert durch den uebergebenen Bruch
     * (unter Verwendung von Kehrwert und Multiplikation).
     */
    public Fraction divide(Fraction f) {
        numerator = numerator * f.denominator;
        denominator = denominator * f.numerator;
        Fraction quotient = new Fraction(numerator, denominator);
        quotient.shorten();
        return quotient;
    }
   
}
 

KonradN

Super-Moderator
Mitarbeiter
Wir helfen Dir die ganze Zeit. Aber wir haben bezüglich Konstruktor mehrfach etwas geschrieben. Und das wurde bisher in keiner Weise behandelt.

Wir haben mehrfach auf die Zeile
* Jeder erzeugte Bruch wird gekuerzt (dazu soll die entsprechende Mehode s.u. verwendet werden).
hingewiesen. Wir haben auf die Probleme, die im Konstruktor drin sind, hingewiesen.

Aber es kam diesbezüglich nie etwas zurück: Keine Rückfrage, keine Anpassung des Konstruktors.

Daher fehlt es uns schlicht an Ansätzen, was wir noch schreiben können. Ich sehe nicht, woran es scheitert. Es ist eben nicht zielführend, dass wir den fertigen Code schreiben sondern Du musst verstehen, was
a) gefordert ist
b) was für Fehler derzeit auftreten
c) wie dies zu beheben ist.

Da ist der folgende Punkt nebensächlich:
Der Aufbau einiger Methoden ist so wie die Methode multiply. Letztere hast Du angepasst. Hast Du verstanden, was da geändert wurde? Dann kannst Du es ja auf die anderen Methoden anwenden (add und divide).
 

KonradN

Super-Moderator
Mitarbeiter
Du bist die Wand.
Zumindest für @mihe7 und mich :)

Aber Spaß bei Seite: Wie ich schon geschrieben habe: Wir wollen Dir ja helfen nur das setzt voraus, dass Du unsere Antworten versuchst zu verstehen. Wenn Dir das gelingt, dann versuche es umzusetzen. Wenn Du an einem der beiden Punkte Probleme hast, dann versuche das uns mitzuteilen. Dabei ist wichtig, nicht einfach nur Aussagen zu wiederholen sondern immer neue Formulierungen zu finden, damit wir eine Chance haben, zu erkennen, woran es bei Dir scheitert.

Und diese Späße sind nicht böse gemeint und richten sich nicht gegen Deine Person. Aber die Situation ist für uns hier (vorsichtig formuliert) so auch recht unbefriedigend.
 
Okay, wenn ich also nicht falsch verstehe, muss ich am Ende der Methoden this.shorten() schreiben, weil ich damit den Konstruktor public shorten() aufrufen kann. Muss ich in den runden Klammern noch Parameter schreiben?
 

KonradN

Super-Moderator
Mitarbeiter
Wenn Du die Methode shorten aufrufen willst: Hat die Methode denn irgendwelche Parameter? Wenn eine Methode Parameter hat, dann muss bei einem Aufruf auch der (bzw. die) Parameter angegeben werden. Wenn eine Methode keine Parameter hat, dann dürfen auch keine Parameter angegeben werden.
 

mihe7

Top Contributor
Okay, wenn ich also nicht falsch verstehe, muss ich am Ende der Methoden this.shorten() schreiben, weil ich damit den Konstruktor public shorten() aufrufen kann. Muss ich in den runden Klammern noch Parameter schreiben?
Da fehlt wohl etwas an Basiswissen.

Der Konstruktor ist das "Teil", das genauso wie die Klasse heißt und fast wie eine Methode aussieht aber keinen Rückgabewert hat. In Deinem Fall ist also public Fraction(int numerator, int denominator) der Konstruktor.

Der Konstruktor wird automatisch aufgerufen, wenn ein Objekt per new erzeugt wird und dient dazu, das neu erzeugte Objekt zu initialisieren.

shorten() ist dagegen eine ganz normale Methode.

Wenn Du also im Konstruktor die Methode shorten() aufrufst, wird bei der Erzeugung einen Bruchs (per new Fraction(...)) dafür gesorgt, dass das neu erzeugte Fraction-Objekt einen bereits gekürzten Bruch darstellt.

Schauen wir uns Deines Code mal im Detail an:
Java:
    // Konstruktor, der aufgerufen wird, wenn man ein neues
    // Objekt per new Fraction(a,b) erzeugt.
    public Fraction(int numerator, int denominator) {
       
        if(denominator<0){ // ist das Argument denominator < 0 ?
            numerator = -numerator;  // dann ändere die Argumente numerator
            denominator = -denominator; // und denominator
        }
        if(denominator == 0){ // ist das Argument denominator 0?
            denominator = 1;  // dann ändere das Argument denominator zu 1
        }
    }

Wenn Du also new Fraction(8,4) aufrufst, wird ein neues Fraction-Objekt erzeugt (numerator und denominator des Objekts sind erstmal 0), und für dieses neue Objekt wird automatisch dieser Konstuktor ausgeführt.

Macht der Konstruktor das, was er tun soll? Das habe ich in #13 bereits geschrieben, dass und warum er das nicht tut. Kommentar #16 hast Du auch ignoriert. Jeder Deiner Brüche wird also als Zähler und Nenner 0 haben.
 
Schreibe ich jetzt this.shorten oder this.shorten()? Ich glaube, das 1. ist richtig, weil einerseits kein Parameter verwendet wird und andererseits ich es in anderen Beispielen nicht mit Klammern gesehen habe.
 

KonradN

Super-Moderator
Mitarbeiter
Das ist etwas, das Du ja direkt ausprobieren kannst. Was sagt der Compiler, wenn Du es ohne Klammern schreibst?

Ansonsten gleich die Erläuterung:
Ein Methodenaufruf hat in Java immer Klammern. In die Klammern kommen die Parameter. Aber auch wenn es keine Parameter gibt, müssen die Klammern gesetzt werden.

Und bezüglich des Wordings:

shorten ist eine Methode.
Konstruktoren sind keine normalen Methoden. Konstruktoren sehen zwar prinzipiell so aus, wie Methoden aber sie haben zwei Abweichungen:
a) Sie heißen genau so, wie die Klasse.
b) Sie haben keinen Rückgabetyp. (Also auch kein void oder so!)
 
Ich muss die Klammern bei this.shorten() verwenden, weil es sonst bei mir als Fehler anerkannt wird.

Die Parameter in den Methoden wie multiply haben den gleichen Namen, Fraction wie die Instanzvariable Fraction. Deshalb muss ich, um darauf zugreifen zu können, schreiben: this.Fraction = ?;

Bezüglich #13: Mein Code entspricht nicht den Kommentaren. Wie soll ich es ändern, damit 1. und 2 erfüllt wird?
 

mihe7

Top Contributor
Java:
public class Fraction {

    private int numerator, denominator;
Du hast hier zwei Instanzvariablen deklariert, nämlich numerator und denominator.

Java:
    public Fraction(int numerator, int denominator) {
        this.numerator = numerator;
    //  |- Instanzv.-|   ^^^^^^^^^ Parameter
        this.denominator = denominator;
    }
Und nein, der Konstruktor ist nicht vollständig.
 

mihe7

Top Contributor
Damit wollte ich die betreffenden Stellen in der Zeile darüber markieren: this.numerator ist die Instanzvariable und auf der rechten Seite bezieht sich das numerator auf den Parameter.
 
Und darunter soll dann der 2. Kommentar aus #13 seinen Code finden. Ich verstehe aber den Kommentar dazu nicht. Negativ darf nur der Zähler sein. Wenn der Nenner negativ ist, wird es trotzdem übergeben (also negativ sein) und soll trotzdem mathematisch korrekt sein. Das und das darauffolgende macht für mich nicht Sinn. Wie soll ich das im Programm schreiben?
 

mihe7

Top Contributor
Wenn der Nenner < 0 ist, werden Zähler und Nenner negiert. Das hattest Du in Deinem Code vom Prinzip her schon richtig verstanden, das Problem war, dass Du die Argumente und nicht die Instanzvariablen geändert hast.
 
Java:
    public Fraction(int numerator, int denominator) {
        this.numerator = numerator;
        this.denominator = denominator;
        
        if(denominator<0){
            this.numerator = -numerator;
            this.denominator = -denominator;
        }
        if(denominator == 0){
            this.denominator = 1;
        }
    }
        
    }
 
Java:
    public Fraction(int numerator, int denominator) {
        this.numerator = numerator;
        this.denominator = denominator;
      
        if(denominator<0){
            this.numerator = -numerator;
            this.denominator = -denominator;
        }
        if(denominator == 0){
            this.denominator = 1;
        }
    }
    this.shorten();
    return this; 
    }
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
Kirby.exe Brüche kürzen Java Basics - Anfänger-Themen 12
J Brüche kürzen Java Basics - Anfänger-Themen 11
B Brüche kürzen Java Basics - Anfänger-Themen 7
S [HILFE] Brüche addieren, multiplizieren, kürzen Java Basics - Anfänger-Themen 17
M OOP Brüche nicht richtig berechnen Java Basics - Anfänger-Themen 3
L Brüche in java Java Basics - Anfänger-Themen 7
G OOP- Brüche addieren Java Basics - Anfänger-Themen 3
O Methoden implementieren, Sichtbarkeiten, Brüche Java Basics - Anfänger-Themen 104
S Zahlenformat für unendliche Brüche? Java Basics - Anfänger-Themen 7
Eileen Brüche addieren in Zwei Klassen mit JOptionPane Java Basics - Anfänger-Themen 4
kb interface / Brüche in java übergeben Java Basics - Anfänger-Themen 3
S Brüche, Fließkommazahlen Java Basics - Anfänger-Themen 3
H Zahlen kürzen Java Basics - Anfänger-Themen 2
Zeppi OOP Bruch kürzen im Konstruktor Java Basics - Anfänger-Themen 2
J Dezimalzahl in Bruch Umwandeln und Kürzen Java Basics - Anfänger-Themen 8
G Code kürzen Java Basics - Anfänger-Themen 5
G code kürzen Java Basics - Anfänger-Themen 16
F String auf E-Mail kürzen Java Basics - Anfänger-Themen 11
F Code kürzen Java Basics - Anfänger-Themen 9
E Methoden Math.Random() kürzen ? Java Basics - Anfänger-Themen 2
J Code kürzen Java Basics - Anfänger-Themen 11
E Arrayeintrag nach Index löschen und Array kürzen Java Basics - Anfänger-Themen 3
E String komprimieren - Kürzen ohne Informationsverlust? Java Basics - Anfänger-Themen 13
A String kürzen Java Basics - Anfänger-Themen 12
K taschenrechner - Fehler beim Kürzen eines Bruches finden Java Basics - Anfänger-Themen 20
J kürzen von brüchen Java Basics - Anfänger-Themen 9
N Datentypen Double nach 2 stellen kürzen Java Basics - Anfänger-Themen 4
D String kürzen, nich abschneiden Java Basics - Anfänger-Themen 9
M Text kürzen Java Basics - Anfänger-Themen 7
M Quelltext kürzen Java Basics - Anfänger-Themen 8
E Interface einfügen und Code kürzen Java Basics - Anfänger-Themen 15
M Programmierung kürzen??? Java Basics - Anfänger-Themen 5
E Kürzen des Quelltextextes Java Basics - Anfänger-Themen 16
U Code kürzen Java Basics - Anfänger-Themen 4
G bruch soweit es geht kürzen Java Basics - Anfänger-Themen 12
A String um 1 Zeichen kürzen ? Java Basics - Anfänger-Themen 6
S String kürzen auf bestimmte Länge Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben