3

我在下面定义了两个类:

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,cBigDecimalinjunkChild而无需再次重写DoSomething()。即使我必须再次编写它,代码也会完全相同,所以应该有一种方法可以让我无需编写它就可以完成这项工作。该DoSomething函数应该检查该类型a1是否具有add正确输入和返回类型的方法,如果是,则调用它而不用担心类型a, b,c是什么。

这可以做到吗?

4

4 回答 4

4

不,你不能这样做——至少在编译时不能。这两种add方法实际上是不相关的——它们不是来自接口或类似的东西。

您可以通过反射来做到这一点(在为 和或类似的东西添加属性之后a-b字段c不能像这样“覆盖”),但这不会非常好。

于 2010-01-04T16:18:14.830 回答
2

您询问的编程语言功能称为鸭子类型,Java 不支持它。你必须坚持你原来的包装方法策略。

于 2010-01-04T16:20:53.180 回答
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();
}

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

于 2010-01-04T18:23:11.717 回答
1

由于 Number (这两个类的最接近的祖先没有 add 方法),您可以先将 BigInteger 转换为 BigDecimal:

new BigDecimal(bi)
于 2010-01-04T16:21:23.897 回答