开发者

how to call method without knowing the class name?

I have defined two classes below:

public class junk 开发者_Python百科{
   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();
   }
}

Unfortunately the above does not work.

What I want to do is to simply change a, b, c to BigDecimal in junkChild without rewriting DoSomething() again. Even if I have to write it again, the code will be exactly the same, so there should be a way I can make this work without having to write it. The DoSomething function should check that the type a1 has an add method of the correct input and return type, and if so, invoke it without being worried about what type a, b, c are.

Can this be done?


No, you can't do this - at least not at compile-time. The two add methods are effectively unrelated - they're not from an interface or anything like that.

You could do it with reflection (after adding properties for a, b and c or something similar - fields can't be "overridden" like this), but it wouldn't be terribly nice.


The programming language feature you're asking about is called duck typing and Java doesn't support it. You'll have to stick with your original wrapper method strategy.


As has been said, Java doesn't do "duck typing" where the two types do not share a useful interface. BigDecimal and BigInteger both extend Number, but the add() method is not part of that interface, so it doesn't help.

I think you need to make explicit what you are operating on in the method parameters of doSomething(). Then you can overrride doSomething() to operate on both types:

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

The second method is simply a conversion method that then calls the real logic in the first method.


since Number (the closest ancestor of both classes doesn't have the add method), you can convert your BigInteger to BigDecimal first:

new BigDecimal(bi)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜