Hi
ich brauche etwas Hilfe bei einer Aufgabe.
Ich soll eine Klasse Fraction erstellen; diese hat als Attribute Zähler und Nenner, die nur in der Klasse sichtbat sind.
Ich soll Methoden schreiben zum
- addieren
- multiplizieren
- umrechnen in eine Fließkomma-Zahl
- Kehrwert bilden
- umrechnen in einen äquivalenen reduzierten Bruch(größter gemeinsamer Teiler-Algorithmus?; soll mit einer while-Schleife implementiert werden)
Den Methoden zum addieren und multiplizieren soll ein Objekt vom Typ Fraction übergeben werden.
Mein Anfang:
Java:
publicclassFraction{publicstaticvoidmain(String[] args){double zähler;double nenner;addieren();}publicstaticvoidaddieren(){
ergebnis=zähler + nenner //Geht es darum 2 Brüche zu addieren oder Zähler und Nenner?}publicstaticvoidmultiplizieren(){}publicstaticvoid umrechnenFließkommaZahl(){}publicstaticvoidkehrwertbilden(){}publicstaticvoidumrechnen(){}}
Muss ich vor den Attributen private schrieben, um sie nur in der Klasse sichtbar zu machen?
Ist das mit dem Addieren so richtig, was ich geschrieben habe?
Attribute sollten (fast) immer private sein, ja. Aber momentan sind das keine Attribute sondern lokale Variablen in der Main-Methode. Ich würde die Main-Methode in eine eigene Klasse machen und dort dann die Fraction-Klasse benutzen. Dann brauchst du noch einen Konstruktor mit zähler und nenner als Parameter bzw. Setter-Methoden. Und die Methoden dann nicht mehr als static definieren.
Ich würde die addieren - Methode so interpretieren, dass ein andere Bruch übergeben wird, welcher zu dem Bruch addiert werden soll.
Steht irgendwo in der Aufgabenstellung, dass die Methoden static sein sollen oder hast du das so gemacht? Diese als static zu deklarieren ergibt in meinen Augen nicht viel Sinn.
Die Methoden in Fraction public,
die Methoden brauchen Parameter,
die Methoden brauchen einen Rückgabetyp,
die Methoden brauchen einen Rückgabewert,
den Sinn der Methode umrechnen habe ich noch nicht verstanden.
Ich würde die addieren - Methode so interpretieren, dass ein andere Bruch übergeben wird, welcher zu dem Bruch addiert werden soll.
Steht irgendwo in der Aufgabenstellung, dass die Methoden static sein sollen oder hast du das so gemacht? Diese als static zu deklarieren ergibt in meinen Augen nicht viel Sinn.
Das ist mir schon klar
Jetzt bist du an der Reihe zu überlegen warum das so ist. Tipp: Überleg dir noch mal wie so eine Java-Klasse aufgebaut sein muss. Wo Methoden deklariert werden könnten etc.
Hier habe mal versucht den Code so zu formatieren wie es üblich ist.. soweit es ging.
Fällt dir nicht selber auch auf dass du tw. Code drin hast der so nicht compilieren kann?
- Befehle außerhalb von Methoden,
- Methodendeklaration außerhalb von Klassen,..
- Fehlende / falsch gesetzte Klammern
@Javinner
Ich weiß, dass einige Methoden so noch nicht richtig sind.
Es bringt allerdings nichts jetzt schon auf so etwas "rumzuhacken" wenn die Formatierung / syntaktische Schreibweise nicht stimmt
Du solltest dir vielleicht auch ein paar Gedanken darüber machen, was man von einer Klasse zur Abbildung von Brüchen eigentlich erwartet. Wie würdest du mit deiner Klasse z.B. die Rechnung 2/3 + 3/4 ausführen? Also wie erzeugst du die Brüche 2/3 und 3/4? Wie rufst du deren Addition auf? Und erwartet man von einer Fraction-Klasse wirklich, dass sie als Ergebnis eine Gleitkommazahl liefert?
Wolltest du nicht die Attribute als private deklarieren? Und wie schon gesagt, die main-Methode gehört nicht in eine Fachklasse. Erstelle eine eigene Main-Klasse dann ist das ganze viel lesbarer. So kann das nicht objektorientiert sein, du brauchst ja am Ende mindestens zwei Fraction-Objekte und da macht das kein Sinn, wenn jede davon eine main-Methode hat. Du darfst den Attributen auch nicht die Werte direkt zuweisen, sonst hat ja jeder Bruch die gleichen Zahlen. Wie gesagt, entweder ein parametrierter Konstruktor oder setter-Methoden.
Du sollst die Attribute zaehler und nenner die nur in der Klasse sichtbar sind anlegen. Die Attribute hast du zwar angelegt, sind aber noch außerhalb der Klasse sichtbar.
Die Struktur der Klasse sieht jetzt soweit richtig aus. Jetzt gilt es die Methoden richtig anzulegen.
Überleg dir mal bei welchen Methoden es sind hat etwas zurückzugeben (wenn ja was) oder ob es Methoden gibt die eventuell nur das Objekt, auf dem die Methode aufgerufen wird, verändern und nichts zurückgeben. (Als kleines Beispiel würde ich hier die add-Methode nehmen welche mMn nur das eigentliche Objekt mit dem übergebenen addieren soll).
Versuch also erstmal die Methodensignaturen aufzuschreiben (ohne eigentliche Implementierung). Mach dir klar welche Methode was machen soll.
Ich möchte dich nicht verwirren, aber als zusätzliche Information für später in deinem Programmiererleben:
Variablen in Java haben einen Gültigkeitsbereich. Wenn du innerhalb einer Funktion Variablen erzeugst, verlieren diese spätestens am Ende der Funktion ihre Gültigkeit und werden wieder zerstört. Aus diesem Grund ist es nicht notwendig die Variablen für das Ergebnis in unterschiedlichen Funktionen unterschiedlich zu benennen.
Java:
publicdoubleaddieren(){double anderezahl =2;double ergebnis = zähler/nenner + anderezahl;// Hier wird eine Variable Ergebnis lokal erzeugtreturn ergebnis;}// hier verliert sie ihre Gültigkeitpublicdoublemultiplizieren(){double anderezahl1 =2;double ergebnis1 = zähler/nenner*anderezahl1;// dito lokale Variable Ergebnis1return ergebnis1;}// Ende der Gültigkeitpublicdoublekehrwertbilden(){double ergebnis3=nenner/zähler;// und Ergebnis3return ergebnis3;}// Ende der Gültigkeit
[/QUOTE]
Aus dem obigen Beispiel: Die Funktion "multiplizieren" "weiß" nichts von der Variablen "ergebnis" aus der Funktion "addieren". Du kannst die Variablen demnach in allen Funktionen gleich benennen. Das erhöht die Lesbarkeit im Gegensatz zu "ergebnis123".
Noch ein kleines Beispiel zur Verdeutlichung:
Java:
publicvoiddoSomething(){int foo =0;// Variable foo deklarieren und initialisierenfor(int i =0; i <10;++i){
foo = foo + i;// foo ist hier bekannt, weil sie in einem höheren Gültigkeitsbereich erzeugt wurdeint bar = foo;// bar deklarieren und initialisieren}// hier endet der Gültigkeitsbereich von barprintln(foo);// foo ist noch im Gültigkeitsbereichprintln(bar);// Fehler: bar ist hier nicht bekannt}// hier endet der Gültigkeitsbereich von foo
Du sollst die Attribute zaehler und nenner die nur in der Klasse sichtbar sind anlegen. Die Attribute hast du zwar angelegt, sind aber noch außerhalb der Klasse sichtbar.
Die Struktur der Klasse sieht jetzt soweit richtig aus. Jetzt gilt es die Methoden richtig anzulegen.
Überleg dir mal bei welchen Methoden es sind hat etwas zurückzugeben (wenn ja was) oder ob es Methoden gibt die eventuell nur das Objekt, auf dem die Methode aufgerufen wird, verändern und nichts zurückgeben. (Als kleines Beispiel würde ich hier die add-Methode nehmen welche mMn nur das eigentliche Objekt mit dem übergebenen addieren soll).
Versuch also erstmal die Methodensignaturen aufzuschreiben (ohne eigentliche Implementierung). Mach dir klar welche Methode was machen soll.
Wolltest du nicht die Attribute als private deklarieren? Und wie schon gesagt, die main-Methode gehört nicht in eine Fachklasse. Erstelle eine eigene Main-Klasse dann ist das ganze viel lesbarer. So kann das nicht objektorientiert sein, du brauchst ja am Ende mindestens zwei Fraction-Objekte und da macht das kein Sinn, wenn jede davon eine main-Methode hat. Du darfst den Attributen auch nicht die Werte direkt zuweisen, sonst hat ja jeder Bruch die gleichen Zahlen. Wie gesagt, entweder ein parametrierter Konstruktor oder setter-Methoden.
Du kannst einen Scanner verwenden, ja. Aber trotzdem müssen die Zahlen die du vom Scanner hast auch irgendwie ins Objekt, daher setter oder parametrierter Konstruktor.
Ja genau und da drin ist einfach nur die main-Methode.
Genau. Du solltest zwei separate Klassen haben. Eine, die die "static main" enthält und in der du später deine Fraction-Objekte erstellst, addierst, Eingaben verarbeitest, Ausgaben machst usw.
Und eine Klasse Fraction.
Diese beiden Klassen sollten in je einer separaten Quelltext-Datei sein.
Du kannst einen Scanner verwenden, ja. Aber trotzdem müssen die Zahlen die du vom Scanner hast auch irgendwie ins Objekt, daher setter oder parametrierter Konstruktor.
Ja genau und da drin ist einfach nur die main-Methode.
Was die Trennung der Main von der Fachklasse betrifft, ja. Jetzt noch den Konstruktor einfügen und Attribute private deklarieren und dann können wir uns der Additions- und der Multiplikationsmethode widmen.
Was die Trennung der Main von der Fachklasse betrifft, ja. Jetzt noch den Konstruktor einfügen und Attribute private deklarieren und dann können wir uns der Additions- und der Multiplikationsmethode widmen.
Ich kenne ja die Aufgabenstellung nicht, die hast du ja nicht so genau gepostet. Aber für mich sind alle deine Methoden (addieren, subtrahieren, multiplizieren und dividieren) im Ansatz falsch. Für mein Begriffe sollst du wahrscheinlich jeweils zwei Brüche addieren, subtrahieren usw. und als Ergebnis jeweils einen neuen Bruch zurückliefern. Schreibst du ja ansatzweise im ersten Post dass addieren einen Bruch als Parameter kriegen soll.
Und ja ich weiss, man kann einen Bruch auch als 3.14/2.09 schreiben aber üblicherweise sind Zähler und Nenner doch ganze Zahlen, d.h. deine Attribute sollten wohl vom Typ int sein ?? Oder wie bestimmst du den ggT bzw. wie wolltest du kürzen ? ggt = 0.001 ??
Ich kenne ja die Aufgabenstellung nicht, die hast du ja nicht so genau gepostet. Aber für mich sind alle deine Methoden (addieren, subtrahieren, multiplizieren und dividieren) im Ansatz falsch. Für mein Begriffe sollst du wahrscheinlich jeweils zwei Brüche addieren, subtrahieren usw. und als Ergebnis jeweils einen neuen Bruch zurückliefern. Schreibst du ja ansatzweise im ersten Post dass addieren einen Bruch als Parameter kriegen soll.
Aufgabe:
A03.3: Brüche
Erstellen Sie eine Klasse Fraction, als Attribute hat diese Klasse Zähler und Nenner, die nur in der Klasse sichtbar sind.
Schreiben Sie Methoden zum addieren, multiplizieren, umrechnen in eine Fließkomma-Zahl, kehrwert bilden und zum
umrechnen in einen äquivalenten reduzierten Bruch (benutzen Sie hier den in der Vorlesung vorgestellten Algorithmus,
implementieren Sie diesen mit Hilfe einer while-Schleife). Den Methoden zum addieren und multiplizieren wird dabei
ebenfalls ein Objekt vom Typ Fraction übergeben.
Ziel: Methoden implementieren
Das war ja nur ein Beispiel von mir, die Parameter im Konstruktor sollten den selben Datentyp haben wie die Attribute, ja. Mach den Scanner und die Eingaben mal raus, das gehört in die Main-Methode, aber das ist momentan nicht so wichtig.
Konstruktor ist richtig aber addieren ist falsch. Die soll einen Bruch als Parameter erhalten !!
Und man addiert dann zwei Brueche indem man den Hauptnenner bildet, die Zaehler jeweils erweitert und dann addiert.
Du sollst ein Objekt mitgeben. Also kein "/", kein Nenner, kein Zähler, einfach nur ein Fraction-Objekt wie es JStein52 schon gepostet hat.
Und reduzier mal die große Lücke im Code nach dem Konstruktor.
public Fraction addiere(Fraction b) {
// Hauptnenner bilden
int common = hauptNenner(this.nenner, b.nenner);
// zwei neue Brüche anlegen die dann passend erweitert werden
Fraction commonA = new Fraction();
Fraction commonB = new Fraction();
commonA = erweitern(common);
commonB = b.erweitern(common);
// neuen Bruch anlegen fuer das Ergebnis
Fraction sum = new Fraction();
// berechne die Summe
sum.zaehler = commonA.zaehler + commonB.zaehler;
sum.nenner = common;
// hier könnte man jetzt noch kuerzen
return sum;
}
Code:
private int hauptNenner(int nenner1, int nenner2) {
int factor = nenner1;
while ((nenner1 % nenner2) != 0) {
nenner1 += factor;
}
return nenner1;
}
Code:
private Fraction erweitern(int common) {
Fraction result = new Fraction();
int factor = common / this.nenner;
result.zaehler = this.zaehler * factor;
result.nenner = common;
return result;
}
public Fraction addieren( Fraction bruch ){ int zähler1=z; int nenner1=v; int ergebnis =(zähler*nenner2)/(nenner*nenner2)+(zähler1*nenner)/(nenner1*nenner); return ergebnis; }