Вопрос об интерфейсах Java - PullRequest
0 голосов
/ 11 марта 2010

Привет У меня есть следующие интерфейсы, которые мне нужно создать. Можете ли вы просто ответить на один вопрос. Я должен создать переменную для хранения значения оператора и значений двух операндов? Если да, должны ли они быть созданы внутри интерфейсов или внутри класса с помощью моего метода main?

interface ArithmeticOperator {

    // Returns the result of applying the operator to operands a and b.
    double operate (double a, double b);

    // Return a String that is the name of this operator.
    String printName ();
}


interface OperatorIterator {

    // Apply the operator op repeatedly to the startValue, for numIterations
    // times, e.g., for numIterations=4 you would return
    //    op (startValue, op (startValue, op (startValue, startValue)))
    double iterate (ArithmeticOperator op, double startValue, int numIterations);

}


public class Exam1 implements ArithmeticOperator, OperatorIterator{

    public double operate(double a, double b) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String printName() {
        String operator ="";
        if(operator.equals("+"))
            return "Add";
        else if(operator.equals("-"))
            return "Sub";
        else if(operator.equals("/"))
            return "Div";
        else if(operator.equals("*"))
            return "Mult";
        else
            return "Unknown Operator";
    }

    public double iterate(ArithmeticOperator op, double startValue, int numIterations) {
        throw new UnsupportedOperationException("Not supported yet.");
    }



    public static void main (String[] argv)
    {
        // Test 1:
        System.out.println ("TEST 1:");
        ArithmeticOperator add = OperatorFactory.get ("add");
        System.out.println ("  1 " + add.printName() + " 2 = " + add.operate (1,2));
        ArithmeticOperator sub = OperatorFactory.get ("sub");
        System.out.println ("  3 " + sub.printName() + " 2 = " + sub.operate (3,2));
        ArithmeticOperator mult = OperatorFactory.get ("mult");
        System.out.println ("  3 " + mult.printName() + " 2 = " + mult.operate (3,2));
        ArithmeticOperator div = OperatorFactory.get ("div");
        System.out.println ("  3 " + div.printName() + " 2 = " + div.operate (3,2));

        // Test 2:
        System.out.println ("TEST 2:");
        ArithmeticOperator add2 = OperatorFactory.get ("add");
        ArithmeticOperator sub2 = OperatorFactory.get ("sub");
        System.out.println ("  Does add2==add? " + add2.equals(add));
        System.out.println ("  Does add2==sub2? " + add2.equals(sub2));

        // Test 3:
        System.out.println ("TEST 3:");
        OperatorIterator opIter = new OpIterator ();
        System.out.println ("  3 * 8 = " + opIter.iterate(add, 3, 8));
        System.out.println ("  3 ^ 4 = " + opIter.iterate(mult, 3, 4));
    }


}

Ответы [ 5 ]

2 голосов
/ 11 марта 2010

Вы используете интерфейсы для определения договора. Переменная обрабатывается конкретной реализацией, например,

public class Add implements ArithmeticOperator(){ 
   @Override double operate (double a, double b){ return a+b;}
}

Если вы хотите что-то с немного большим поведением в качестве основы, вы можете использовать абстрактный класс.

0 голосов
/ 11 марта 2010

Интерфейс не является абстрактным классом .

Интерфейсы необходимы для определения общего протокола между классами, где общий протокол означает только сигнатуры методов, которые видимы из других классов, и то, что они способны делать. Интерфейсы не могут «удерживать» значения.

Абстрактные классы более мощные, они используются для определения общей части между классами, либо procol, либо реализацией. Вы можете смешивать предопределенное поведение с абстрактными методами и позволять подклассам реализовывать их.

Что это значит?

Это означает, что вы используете интерфейс, когда хотите дать своим классам те же методы, но если вы хотите определить общее поведение, вы должны использовать абстрактный класс или класс отца, из которого объявляются конкретные реализации.

В вашем примере вы можете позволить типу класса быть вашим фактическим типом операции:

interface ArithmeticOperation
{
  public double operate(double a, double b);
}

class AddOperation implements ArithmeticOperation
{
  public double operate(double a, double b)
  {
    return a + b;
  }
}

Вы также можете использовать подклассы для определенных вещей (учтите, что следующий пример тривиален и не очень подходит):

class PowerOperation implements UnaryOperation
{
  public double operate(double a)
  {
    return a*a;
  }
}

class CubeOperation extends PowerOperation
{
  public double operate(double a)
  {
    return super.operate(a)*a;
  }
}

Вам следует избегать цепочки IFs просто для распечатки вещей, потому что ваши классы уже знают, какого они типа, и вы можете делегировать им эту работу:

class AddOperation{ public String printVal() { return "ADD"; } }
class SubOperation{ public String printVal() { return "SUB"; } }
0 голосов
/ 11 марта 2010

Решите, является ли ваша переменная изменчивой или нет. Если да - тогда объявите это в классе, если неизменный - в интерфейсе. Переменные интерфейса финальные по умолчанию.

0 голосов
/ 11 марта 2010

Оператор, похоже, не имеет состояния, просто выполняет некоторые вычисления и возвращает результат. Так что ответ - нет, не храните его в состоянии объекта (или переменной). Для чего вам это нужно?

0 голосов
/ 11 марта 2010

Значения операндов передаются вызывающим в качестве параметров вашему методу. Оператор, по-видимому, подразумевается в конкретной реализации ArithmeticOperator. Подклассы ArithmeticOperator должны определять тело операции, в которой оператор будет «жить».

Обратите внимание, что его не нужно «хранить» где-либо отдельно; это просто логика.

Например:

public class PlusOperator implements ArithmeticOperator {
    double operate(double a, double b) {
        return a+b;
    }
}

В вашем методе printName вам нужно будет проверить фактический тип ArithmeticOperator, а не String (которого у вас нет и не нужно).

Как:

if (op instanceof PlusOperator) {
    System.out.println("+");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...