如何在不知道类名的情况下调用方法?

时间:2010-01-04 16:14:49

标签: java class field overloading anonymous

我在下面定义了两个类:

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();
   }
}

不幸的是,上述方法无效。

我想要做的只是将abc更改为BigDecimal中的junkChild,而无需再次重写DoSomething()。即使我必须再次编写它,代码也会完全相同,所以应该有一种方法可以让它无需编写即可完成。 DoSomething函数应检查类型a1是否具有正确输入和返回类型的add方法,如果是,则调用它而不必担心类型abc是。

可以这样做吗?

4 个答案:

答案 0 :(得分:4)

不,你不能这样做 - 至少在编译时不行。这两种add方法实际上是无关的 - 它们不是来自界面或类似的东西。

您可以使用反射(在添加abc或类似内容的属性后执行此操作 - 字段不能像这样被“覆盖”),但它不会非常好。

答案 1 :(得分:2)

您要问的编程语言功能称为duck typing,Java不支持它。你必须坚持原始的包装方法策略。

答案 2 :(得分:2)

如前所述,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();
}

第二种方法只是一种转换方法,然后在第一种方法中调用实际逻辑。

答案 3 :(得分:1)

因为Number(两个类的最近祖先没有add方法),所以你可以先将BigInteger转换为BigDecimal:

new BigDecimal(bi)