как реализовать Java-эквивалент указателей на функции через абстрактные классы - PullRequest
3 голосов
/ 22 февраля 2011

Я пытаюсь создать простой 4-х функциональный калькулятор, используя таблицу переходов без регистра переключателя или операторов if / else.Я понимаю, что могу создать таблицу переходов с помощью указателей на функции, но я вроде как отключился.Я начал с сложения и вычитания части программы, но пытаюсь понять дизайн / стратегию использования.Я также получаю сообщение об ошибке при помещении метода в массив, так что вот что у меня есть:

public class Calculator {

          public abstract class Functor{

            abstract double Compute(double op1, double op2);
            }

     class Addition extends Functor
    {

        public double Compute(double op1, double op2){ return op1 + op2;}
    }

    class Subtraction extends Functor
    {

        public double Compute(double op1, double op2){ return op1 - op2;}
    }



    public static void main(String[] args) {

        Functor add = new Addition();     // Problem here
        Functor sub = new Subtraction();  // and here



    }
}

любая помощь или идеи для шага в правильном направлении, очень ценится!заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 22 февраля 2011

Давайте попробуем это вместо:

public enum Operation {
  PLUS("+") {
    double apply(double x, double y) { return x + y; }
  },
  MINUS("-") {
    double apply(double x, double y) { return x - y; }
  },
  TIMES("*") {
    double apply(double x, double y) { return x * y; }
  },
  DIVIDE("/") {
    double apply(double x, double y) { return x / y; }
  };
  private final String symbol;

  Operation(String symbol) {
    this.symbol = symbol; 
  }

  @Override public String toString() {
    return symbol; 
  }
  abstract double apply(double x, double y);
}

Это будет работать, только если вы используете Java 5 или более позднюю версию, которая имеет обобщенные и перечисления. Это дает вам статический набор операций. Вы можете получить к ним доступ, набрав Operation.PLUS или Operation.MINUS и т. Д.

Чтобы проверить это, попробуйте это:

public static void main(String[] args) {
  double x = Double.parseDouble(args[0]);
  double y = Double.parseDouble(args[1]);

  for (Operation op : Operation.values())
    System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}

За дополнительной информацией обращайтесь к Джошуа Блоху Effective Java, Second Edition .

Стоит отметить, что в Java нет понятия «указатели на функции». Скорее вы просто пишете интерфейс и пишете класс, который реализует этот интерфейс. Правильный класс для использования выбран во время выполнения; следовательно, это «таблица переходов», но она скрыта за семантикой объектно-ориентированного программирования. Это известно как полиморфизм .

2 голосов
/ 22 февраля 2011

Хотя это неплохо (если не считать конструкторов, которые работают правильно), я бы сделал это иначе, используя анонимные классы.

abstract class Functor {


    public abstract double compute(double a, double b);

    public static void main(String[] args) {
        Functor add = new Functor() {
            // defining it here is essentially how you do a function pointer
            public double compute(double a, double b) { return a + b; }
        };

        Functor subtract = new Functor() {
            public double compute(double a, double b) { return a - b; }
        };

        System.out.println(add.compute(1.0,2.0));
        System.out.println(subtract.compute(1.0,2.0));

    }

}

Результат:

C:\Documents and Settings\glowcoder\My Documents>java Functor
3.0
-1.0

C:\Documents and Settings\glowcoder\My Documents>
0 голосов
/ 22 февраля 2011

У вас нет конструкторов для передачи аргументов вашим подклассам, я не понимаю, как вы думаете, opt1 и opt2 будут установлены без каких-либо конструкторов с такими параметрами.Это не правильный код Java прямо сейчас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...