Search code examples
javabigdecimal

Class extended to BigDecimal returns object from superclass type


I want to do some calculations with money. In order to prevent rounding errors I decided to use BigDecimal instead of double or float. Now I think, this wasn't a good idea, because it makes calculations extremly difficult.

I created a class named Euro that extends from BigDecimal in order to override the toString and equals methods.

Now, if I want to add a number to an Euro object, I would do it like

Euro sum = (new Euro(10)).add(new Euro(15));

The problem here is that add(...) returns an object from class BigDecimal which I can not cast to Euro, so I added this to the Euro class:

public Euro add(Euro euro){
    return new Euro(euro.add((BigDecimal) this).floatValue());
}

What can I do now, instead of rewriting all methods from BigDecimal in Euro? I guess, the best solution is to use an integer for cents instead of BigDecimal, because than I can write

int sumCents = 1000 + 1500;

instead of the long term above.


Solution

  • It would be better to favor composition over inheritance in this case. When you're subclassing BigDecimal to make Euro, you are saying that a Euro is a BigDecimal. It would be more accurate to say that an amount of Money has a BigDecimal (or in general, an amount). It also has a symbol, here a Euro.

    You could also use a different implementation, e.g. number of cents as you already have thought of, to store the amount as an integer. This is a clue that inheriting from BigDecimal isn't correct. Also, it doesn't make sense to call pow on a Euro, even though it makes sense on a BigDecimal. A Euro is not a BigDecimal.

    Besides, calling floatValue (or doubleValue) just to convert to Euro would have defeated the point of using BigDecimal in the first place - to avoid floating-point round-off errors when representing an amount of money.

    When you use composition, then you can expose only the methods you want, e.g. add and subtract, without overriding methods and creating new subclass objects during each mathematical operation. The mathematical operations are done on an instance variable, not on the class as a whole, as an implementation detail.