автоматический вызов функции Java - PullRequest
1 голос
/ 09 февраля 2010

у меня есть математический класс, который хранит представление выражений в списках n-массивов в настоящее время у меня есть три класса AdditionArray MultipleArray и Variable, все они реализуют мой интерфейс Number.

public interface Number {

  public Number Multiply(Number number);

в классах, которые реализуют Number, у меня перегружены операции, такие как Multiply, например,

public class MultipleArray extends ArrayList<Number> implements Number{
  public Number Multiply(AdditionArray number);
  public Number Multiply(Number number){throw new Exception("woops");}

Дело в том, что Java не вызывает автоматически перегруженную функцию во время выполнения. это кажется, чтобы выяснить это во время компиляции

например

Number someNumber = new MultipleArray();
Number someOtherNumber = new AdditonArray();

MultipleArray result2 = someNumber.Multiply(someOtherNumber); //calls the correct function

Number result2 = someNumber.Multiply(someOtherNumber); // throws the woops exception

почему java делает это. и есть ли другой способ, которым я могу реализовать это. какая-то фабрика например?

Cheers, Mark

Ответы [ 3 ]

2 голосов
/ 09 февраля 2010

В Java перегрузка является типом полиморфизма во время компиляции, в то время как переопределение является типом полиморфизма во время выполнения. См. В чем разница между переопределением метода и перегрузкой метода в Java? .

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

1 голос
/ 09 февраля 2010

Как сказал Билл К., Java определяет это во время компиляции, и это по замыслу.

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

Использование Generics - это еще один вариант, который улучшит безопасность вашего типа, но я не знаю достаточно о вашем коде, чтобы сказать, будет ли он работать вокруг. Универсальный числовой интерфейс может выглядеть так:

 public interface Number<T extends Number> {
       public T multiply(Number<? extends T> number);
 }

Обобщения могут быть странными по краям, поэтому, возможно, стоит просто отказаться от безопасности типов и приступить к проверке типа параметра.

1 голос
/ 09 февраля 2010

Я на самом деле не смотрел на ваш код, но просто ответил на ваш основной вопрос - Java выясняет, что вызывать во время компиляции, основываясь на ближайшем типе. Если бы он делал это во время выполнения, это был бы динамический язык.

Java удивительно быстр для того, что он делает, но он получает большую часть своей скорости, не думая так много во время выполнения. Обычно он в 10 раз быстрее, чем Python, и в 100 раз быстрее, чем Ruby.

Если вы хотите большей гибкости в этом, я предлагаю вам вообще не использовать привязки Java, а создать объект «Операция» и вручную привязать его к «Числам». Таким образом, вы можете сделать довольно крутое алгебраическое дерево из объектов. Если ничего другого, это весело - я делал это несколько раз. Это все равно будет чертовски быстро.

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