【问题标题】:Class extended to BigDecimal returns object from superclass type扩展为 BigDecimal 的类从超类类型返回对象
【发布时间】:2018-10-02 04:51:37
【问题描述】:

我想用钱做一些计算。为了防止舍入错误,我决定使用 BigDecimal 而不是 double 或 float。现在我想,这不是一个好主意,因为它使计算变得极其困难。

我创建了一个名为 Euro 的类,它从 BigDecimal 扩展来覆盖 toString 和 equals 方法。

现在,如果我想向欧元对象添加一个数字,我会这样做

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

这里的问题是 add(...) 从 BigDecimal 类返回一个我不能转换为 Euro 的对象,所以我将它添加到 Euro 类:

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

我现在可以做什么,而不是用 Euro 重写 BigDecimal 的所有方法?我想,最好的解决方案是使用整数而不是 BigDecimal,因为我可以写

int sumCents = 1000 + 1500;

而不是上面的长期。

【问题讨论】:

  • 不要扩展 BigDecimal。它不应该被延长。它实际上应该是最终版本,这不仅是因为他们忘记在第一个版本中将其定为最终版本,而是保持这种状态以保持向后兼容。如果您想创建一个 Euro 类,请使其使用(即包装)BigDecimal。不延长它。不知道为什么不直接使用 BiDecimal,以及为什么将结果转换为浮点值,因为您正是想避免使用浮点数。

标签: java bigdecimal


【解决方案1】:

在这种情况下,最好支持组合而不是继承。当您将BigDecimal 子类化为Euro 时,您是在说Euro BigDecimal。更准确地说,Money 的数量 具有 BigDecimal(或一般而言,数量)。它还有一个符号,这里是欧元。

您也可以使用不同的实现,例如您已经想到的美分数,将金额存储为整数。这是从BigDecimal 继承不正确的线索。此外,在Euro 上调用pow 是没有意义的,即使在BigDecimal 上是有意义的。 Euro 不是 BigDecimal

此外,调用floatValue(或doubleValue)只是为了转换为Euro,首先会破坏使用BigDecimal的意义——以避免在表示金额时出现浮点舍入错误钱。

当你使用组合时,你可以只公开你想要的方法,例如addsubtract,没有在每个数学运算期间覆盖方法和创建新的子类对象。数学运算是在一个实例变量上完成的,而不是在整个类上,作为一个实现细节。

【讨论】:

  • 感谢您的回答。我决定为美分解决方案选择整数。
  • @PhilippNiedergesäß:如果您使用美分,则无法准确计算百分比或年金。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
  • 2021-11-12
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
相关资源
最近更新 更多