как вызвать метод, не зная имени класса? - PullRequest
3 голосов
/ 04 января 2010

Я определил два класса ниже:

public class junk {
   private BigInteger a = BigIngeger.valueOf(1), b=BigInteger.valueOf(2), c;

   public void DoSomething() {
      c = a.add(b);
   }

   // ... other stuff here
}

public class junkChild extends junk {
   private BigDecimal a = BigDecimal.valueOf(1), b=BigDecimal.valueOf(2), c;
   // I want a, b, c to override the original BigInteger a,b,c 
   // ... other stuff here
}     

public class myClass {
   public static void main(String args[]) {
      junk a1 = new junkChild();
      a1.DoSomething();
   }
}

К сожалению, выше не работает.

Я хочу просто изменить a, b, c на BigDecimal в junkChild, не переписывая DoSomething() снова. Даже если мне придется написать это снова, код будет точно таким же, поэтому должен быть способ, которым я мог бы сделать эту работу без необходимости писать это. Функция DoSomething должна проверять, имеет ли тип a1 метод add правильного типа ввода и возврата, и, если это так, вызывать его, не беспокоясь о типе a, b, c являются.

Можно ли это сделать?

Ответы [ 4 ]

4 голосов
/ 04 января 2010

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

Вы можете сделать это с отражением (после добавления свойств для a, b и c или чего-то подобного - поля не могут быть "переопределены", как это), но это было бы ужасно приятно.

2 голосов
/ 04 января 2010

Как уже было сказано, Java не выполняет "типизацию", когда два типа не имеют полезного интерфейса. BigDecimal и BigInteger расширяют Number, но метод add () не является частью этого интерфейса, поэтому он не помогает.

Я думаю, вам нужно четко указать, над чем вы работаете, в параметрах метода doSomething (). Затем вы можете переопределить doSomething () для работы с обоими типами:

public BigDecimal doSomething(BigDecimal a, BigDecimal b) {
        return a.add( b );
}

public BigInteger doSomething(BigInteger a, BigInteger b) {
    BigDecimal x = new BigDecimal(a);
    BigDecimal y = new BigDecimal(b);
    BigDecimal z = doSomething(x, y);
    return z.toBigInteger();
}

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

2 голосов
/ 04 января 2010

Функция языка программирования, о которой вы спрашиваете, называется duck typing , и Java ее не поддерживает. Вы должны придерживаться своей оригинальной стратегии метода обертки.

1 голос
/ 04 января 2010

, поскольку Number (ближайший предок обоих классов не имеет метода add), вы можете сначала преобразовать свой BigInteger в BigDecimal:

new BigDecimal(bi)
...