Taschenrechner mit OOP

Saheeda

Mitglied
Hallo,
ich hab n kleines Problem. Ich arbeite zurzeit an nemTaschenrechner, der über die Konsole arbeiten soll. Meine Funktionen arbeiten alle, wie sie sollen, kurz gesagt, das Ding läuft.

Jetzt soll ich ihn aber objektorientiert überarbeiten.
Eigentlich bin ich der Meinung, das Prinzip von OOP verstanden zu haben, trotzdem fällt es mir grade schwer, nen Ansatz zu finden.
Google spuckt mir ne Menge fertige Lösungen aus, ich bräuchte aber vor allem nen Tipp, wie ich überhaupt rangehen soll.
Sonst stehe ich beim nächsten Problem wieder hier....
 

Bullet1990

Mitglied
Objektorientiert bedeutet, dass du Objekte erzeugst. Das heißt du musst Klassen schreiben und diese danach irgendwo instantiieren, d. h. Objekte erzeugen. Bei einem Taschenrechner ist das ein wenig schwierig, da ich nicht wüsste, wo es Sinn macht Objekte zu erzeugen. Du könntest aber beispielsweise für jede arithmetische Operation eine Klasse erstellen. Zum Beispiel eine Klasse "Number", die nur eine Zahl als Feld erhält. Danach könntest du noch eine Klasse "Substraction" implementieren, die die Methode Number substract(Number firstNumber, Number secondNumber) enthält. Diese Methode subtrahiert dann firstNumber und secondNumber (über getter der Klasse Number). firstNumber und secondNumber wären in diesem Fall dann Objekte.

Je nachdem, was das ganze Ding leisten soll, könntes du eine extra Klasse für ganze Ausdrücke schreiben (für Klammerausdrücke z.B.).
Der Sinn davon wird wohl sein, dass du Objekte an Methoden weitergibst, auswerten lässt und neue Objekte zurückbekommst.

Zum Beispiel die Rückgabe für die substract-Methode wäre es sowas wie: return new Number(Substraction.substract(firstNumber, secondNumber));
Wobei die Numbers dann als Parameter übergeben wurden.

Ich hoffe, dass es soweit geholfen hat.
 

ComFreek

Mod | @comfreek
Moderator
Hallo,

erst neulich habe ich ein ähnliches Programm geschrieben, welches im Kern auch mit arithmetischen Rechenoperationen umgehen musste. Da kann man durchaus einige Klassen haben!

Weißt du, was ein Abstract Syntax Tree (AST) ist? Weißt du, was "parsen" bedeutet?
Hier könnte man Klassen und Objekte gut gebrauchen, um den AST abzubilden.
 

Bullet1990

Mitglied
Hallo,

erst neulich habe ich ein ähnliches Programm geschrieben, welches im Kern auch mit arithmetischen Rechenoperationen umgehen musste. Da kann man durchaus einige Klassen haben!

Weißt du, was ein Abstract Syntax Tree (AST) ist? Weißt du, was "parsen" bedeutet?
Hier könnte man Klassen und Objekte gut gebrauchen, um den AST abzubilden.

Genau das ist die einzige sinnvolle Anwendung, in der in diesem Fall Klassen verwendet werden können. Aber ich habe eher das Gefühl, dass ihm eine typische Anfängeraufgabe gestellt wurde, in der er lernen soll Klassen und Objekte zu verwenden. Daher habe ich nur den Begriff "Ausdrücke" verwendet, um ihn nicht mit Parsing zu verwirren. Wenn er einen Lehrer/Dozent hat, der meinen ehemaligen Dozenten ähnelt, dann wird er sich garantiert noch damit auseinandersetzen müssen, wenn seine Aufgaben aufeinander aufbauend sind.
 

Saheeda

Mitglied
@ComFreek
;-)

Nein, ich hab bisher noch nicht mit einem AST gearbeitet und parsen habe ich bisher nur als synonym für Konvertieren o.ä. gehört.


@Bullet1990
Ja, sowas in der Art. Ich soll mich halt mit OOP vertraut machen und zeigen, ob ich die Grundprinzipien verstanden habe und anwenden kann.
Ich würde die Rechenoperationen gerne nochmal irgendwie "bündeln" wäre es sinnvoll, z.B. alle Grundrechenoperationen von einer (abstract) Class, alle Wurzel- und Potenzfunktionen von einer anderen (abstract) Class etc. abzuleiten? Oder gibts dafür nen besseren Weg?

P.S.: Sie, nicht er, soviel Zeit muss sein ;-)
 
Zuletzt bearbeitet:

ComFreek

Mod | @comfreek
Moderator
Parsen ~ Konvertieren einer formalen Sprache in einen Baum

Bündeln / klassifizieren ist gut, aber ich würde die Operationen nach einem anderen Kriterium gruppieren, und zwar nach der Anzahl der Operanden. Die meisten Rechenarten sind nur unäre oder binäre Operationen.

PS: Man hätte nur auf dein Profilbild schauen müssen :p
 

Saheeda

Mitglied
Ok, ich habe das offenbar doch noch nicht richtig verstanden.

Ich habe hier meine Klasse Addition:
Java:
package calculator;

public class Addition extends Base {

private double sum1;
private double sum2;
private double resultAdd;


public double add() { /////<---- Abbruch
this.sum1 = super.memory.pop();
this.sum2 = super.memory.pop();
this.resultAdd = this.sum1 + this.sum2;
memory.push(resultAdd);
return resultAdd;
}

public double getResultAdd() {
return this.resultAdd;
}


}



Und meine Klasse Calculator:

Java:
package calculator;

import java.util.Stack;
import java.lang.*;

public class Calculator {

public Stack<Double> memory;

public Calculator() {
this.memory = new Stack<>();

}

public static void main(String[] args) {

Calculator calc = new Calculator();
System.out.println("Zahlen ins Memory");
calc.memory.push(1.0);
calc.memory.push(2.0);
calc.memory.push(3.0);
calc.memory.push(4.0);
calc.memory.push(5.0);

System.out.println(calc.memory.peek());
Addition b = new Addition();
calc.memory.push(b.add());
System.out.println(calc.memory.peek());

}

}

Was will ich machen?
Mein Taschenrechner soll einen Stack "Memory" besitzen. Rufe ich eine Methode auf, soll er sich die notwendigen Zahlen vom Stack nehmen, miteinander verrechnen und wieder auf den Stack zurücklegen.

Mein AdditionTest funktioniert, zur Laufzeit bekomme ich eine EmptyStackException, sobald er die Addition ausführen soll und in die Klasse Addition geht. Ich verstehe aber nicht warum. Mit super.memory greife ich doch auf den Stack des Calculators zu?
 
Zuletzt bearbeitet:

sheel

I love Asm
Hi

was ist denn die Klasse Base?

Offtopic: Dass es einen Comfreak wirklich auch gibt ist mir neu :D
 

Saheeda

Mitglied
@sheel
Ich möchte die Rechenoperationen wie gesagt irgendwie zusammenfassen, das ist die erste Gruppe. Addition direkt von Calculator abzuleiten hilft auch nicht.

Wenn ich den Stack direkt im Konstruktor besetze, klappts, ansonsten erbt Addition nen leeren Stack.
Ich muss es also so hinkriegen, dass zwar alle auf denselben Stack zugreifen (Vererbung?) aber trotzdem zur Laufzeit der Stack verändert werden kann...