views:

210

answers:

4

I have defined two classes below.

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

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

+4  A: 

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.

Jon Skeet
the most to-the-point answer. Out of curiosity, why can do this with `System.out.print`?(We can define a `toString` method for any arbitrary class)
Jus12
+2  A: 

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.

Asaph
+1  A: 

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)
jspcal
+2  A: 

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.

Matthew Flynn