дизайн на класове и конструктори за програма за аритметични изрази в Java

Трябва да програмирам просто представяне на аритметичен израз в Java. аритметичният израз може да има само знаци +/- и трябва да се представя в класовете по следния начин:

Израз - абстрактен клас

AtomicExpression - разширява Expression клас и трябва да представлява атомно число (като:5/9/332...)

CompoundExpression - Абстрактен клас, който разширява Expression и трябва да съдържа 2 екземпляра на Expression.

AdditionExpression/SubtractionExpression - два класа, които разширяват CompoundExpression и ще представляват израз за събиране/изваждане (напр. 5+3/9-2...)

проблемът ми е с класа CompoundExpression и двата класа, които трябва да наследят от него (AdditionExpression и SubtractionExpression). Не знам как да напиша тези класове, кои параметри трябва да поставя във всеки клас и как да ги представя. Ето какво написах до сега:

package Q1;

public abstract class Expression {

    /*Empty Constructor for Expression object */
    public Expression(){
    }


    /*Calculate the value of the expression
     * @return double This the value of the expression
     */
    public double calculate(){
        String toClac = new String(this.expression); //Copy the expression to calculate to temporary object
        double answer=0;
        int i=1, operator = 0; //0 signal + operator and 1 signal - operator.

        while (toClac!=null && !toClac.isEmpty()){
            //Assumes correct input - start with a digit and not a sign '+' or '-' 
            while (i<toClac.length() && Character.isDigit(toClac.charAt(i)))
                    i++;
            // i equal to the first index that is not a number in the expression


            if (operator == 0){
                answer += Integer.parseInt(toClac.substring(0,i));
            }else answer -= Integer.parseInt(toClac.substring(0,i));

            if (i<toClac.length()) //mean that while stopped because found char that is not number
            {
                //check if the next operator is - or +
                if (toClac.charAt(i)=='-')
                    operator = 1;
                else operator = 0;
                toClac = toClac.substring(i+1,toClac.length()); //cut and save the continue of the string to parse
            }else toClac = null;
            i=0;
        }
        return answer;
    }

    /*
     * Check if two expressions are equal. two expressions are equals if their calculated value is the same 
     * @Override equals - return true if two expressions are equals
     */
    public boolean equals(Object second)
    {
        double firstAnswer, secondAnswer;
        firstAnswer = this.calculate();
        secondAnswer = ((Expression)(second)).calculate();
        return (firstAnswer == secondAnswer);
    }
}

package Q1;

public class AtomicExpression extends Expression {

    int numericExpression;

    //maybe delete
    /*Empty Constructor for AtomicExpression object */
    public AtomicExpression(){
        super();
    }

    /*Constructor for AtomicExpression object*/
    public AtomicExpression(int realNum){
        super();
        this.numericExpression = realNum;
    }

    /*Return the string representation of the expression  
     */
    public String toString(){
        return Integer.toString(this.numericExpression);
    }
}

package Q1;

public abstract class CompoundExpression extends Expression {

    Expression firstOperand, secondOperand;

    //Constructor of CompundExpression object containing two expressions
    public CompoundExpression(Object first, Object second){
        if(first instanceof Integer)
            this.firstOperand = new AtomicExpression((Integer)(first));
        else this.firstOperand = (Expression)first;

        if(second instanceof Integer)
            this.secondOperand = new AtomicExpression((Integer)(second));
        else this.secondOperand = (Expression)second;
    }

}

пакет Q1;

//Клас, представляващ израз за добавяне public class AdditionExpression extends CompoundExpression{

public AdditionExpression(Expression first, Expression second){
    super(first, second);
}


public String toString(){
    String str = this.firstOperand.expression+ " + " + this.secondOperand.expression;
    return str;
}

}

package Q1;

//Class representing an subtraction expression
public class SubtractionExpression extends CompoundExpression{
    int left, right;

    public SubtractionExpression(Expression first, Expression second){
        super(first, second);

    }

    public String toString(){
        String str = this.firstOperand.expression+ " - " + this.secondOperand.expression;
        return str;
    }

}

person Yuval Levy    schedule 27.04.2014    source източник


Отговори (1)


Мисля, че не сте разбрали принципа на това упражнение и принципа на абстрактния клас и полиморфизма.

Един израз има метод Calculate(), който връща стойността на този израз. Този метод трябва да е абстрактен, защото в зависимост от действителния подклас на Expression, методът калкулация() няма да направи същото.

Ето един атомен израз: 15. За такъв израз методът калкулация() е много лесен за прилагане: той просто трябва да върне стойността на числото: 15. Следователно атомният израз има едно поле от тип double и неговия калкулатор( ) просто връща тази двойна стойност.

Съставният израз е малко по-сложен: той има два операнда (т.е. две полета) от тип Expression. Двата операнда се комбинират заедно, за да се изчисли действителната стойност. Но CompoundExpression отново е абстрактен клас: начинът, по който се комбинират двата операнда, зависи от действителния подклас.

AdditionExpression е конкретен подклас на CompoundExpression: той взема двата си операнда, изчислява стойността им (използвайки метода им calculate()) и ги комбинира, като ги добавя:

public double calculate() {
    return a.calculate() + b.calculate();
}

SubtractionExpression прави същото, но вместо това с изваждане:

public double calculate() {
    return a.calculate() - b.calculate();
}

Целта тук не е да ви накара да анализирате низ. Целта е просто да ви накара да представите аритметичен израз като обект, използвайки полиморфизъм:

(a + b) - (c + d)

is a

Subtraction(a + b, c + d)

което е а

Subtraction(Addition(a, b), Addition(c, d))

което е а

Subtraction(Addition(Atomic(a), Atomic(b)), Addition(Atomic(c), Atomic(d)))
person JB Nizet    schedule 27.04.2014
comment
Благодаря ти много!! Мисля, че започвам да разбирам как да го направя. това, което не разбирам, е как трябва да се декларира Expression в класа на тестер? например как атомният номер ще бъде деклариран в класа на тестер? - person Yuval Levy; 27.04.2014
comment
Така че, ако тогава... какво трябва да има в класа CompoundExpression? ако е абстрактен клас и няма методи в него (?) - person Yuval Levy; 27.04.2014
comment
възможно ли е така да изглежда CompoundExpression: пакет Q1; публичен абстрактен клас CompoundExpression extends Expression { Expression firstOperand, secondOperand; } - person Yuval Levy; 27.04.2014
comment
По принцип да. Трябва просто да съдържа двата операнда и да дефинира конструктор. Полетата и конструктора трябва да бъдат защитени. Може също така да направи полетата частни, да има абстрактен метод double doCalculate(Expression e1, Expression e2) и да приложи метода калкулация() като public final double calculate() {return doCalculate(operand1, operand2);} Подкласовете за изваждане и добавяне тогава биха заменили doCalculate(e1, e2). Но бих го направил просто и просто ще направя полетата защитени. - person JB Nizet; 27.04.2014