public class Money extends Quantity<Currency> {
private static final long serialVersionUID = 4586753888134642487L;
private static final Currency DEFAULT_CURRENCY = Currency.getInstance("CNY");
private static final int DEFAULT_SCALE = 2;
public static final Money ZERO = new Money();
public static final Money ONE_CHIAO = new Money(DEFAULT_CURRENCY, new BigDecimal("0.1"));
public static final Money ONE_YUAN = new Money(DEFAULT_CURRENCY, new BigDecimal("1"));
public Money() {
this(DEFAULT_CURRENCY, new BigDecimal(0));
}
public static Money getZero(){
return ZERO;
}
public Money(Currency currency, BigDecimal amount) {
super();
setUnits(currency);
setAmount(amount);
}
public Money(Quantity<Currency> quantity) {
this(quantity.getUnits(),
new BigDecimal(quantity.getAmount().toString()));
}
public Money(BigDecimal amount) {
this(DEFAULT_CURRENCY, amount);
}
public Money(double amount) {
this(DEFAULT_CURRENCY, new BigDecimal(amount));
}
public void setAmount(BigDecimal amount) {
super.setAmount(amount.setScale(DEFAULT_SCALE, RoundingMode.HALF_UP));
}
public BigDecimal getAmount() {
return ((BigDecimal)super.getAmount()).setScale(DEFAULT_SCALE, RoundingMode.HALF_UP);
}
/**
* 加
*/
public Quantity<Currency> plus(Quantity<Currency> another){
return plus((Money)another);
}
/**
* 加
*/
public Money plus(Money another) {
BigDecimal amount = this.getAmount().add(another.getAmount());
return new Money(this.getUnits(),amount);
}
/**
* 加
*/
public Money plus(BigDecimal another) {
return new Money(this.getUnits(),this.getAmount().add(another));
}
/**
* 加
*/
public Money plus(double another) {
return plus(new Money(another));
}
/**
* 减
*/
public Quantity<Currency> minus(Quantity<Currency> another){
return minus((Money)another);
}
/**
* 减
*/
public Money minus(Money another) {
BigDecimal amount = this.getAmount().subtract(another.getAmount());
return new Money(this.getUnits(),amount);
}
/**
* 减
*/
public Money minus(double another) {
return minus(new Money(another));
}
/**
* 乘
*/
public Money multiply(BigDecimal another) {
BigDecimal amount = this.getAmount().multiply(another);
return new Money(this.getUnits(), amount);
}
/**
* 乘
*/
public Money multiply(double another) {
return this.multiply(new BigDecimal(another));
}
/**
* 除
*/
public Money divide(BigDecimal divisor) {
BigDecimal amount = this.getAmount().divide(divisor, DEFAULT_SCALE, RoundingMode.HALF_UP);
return new Money(this.getUnits(), amount);
}
/**
* 除
*/
public Money divide(double divisor) {
return this.divide(new BigDecimal(divisor));
}
/**
* 取反
*/
public Money negative() {
return new Money().minus(this);
}
/**
* 取绝对值
*/
public Money abs() {
return new Money(this.getAmount().abs());
}
/**
* 舍掉分角
*/
public Money floorChiao() {
double amount = Math.floor(getAmount().doubleValue());
return new Money(this.getUnits(), new BigDecimal(amount));
}
/**
* 舍掉分
*/
public Money floorCent() {
double amount = Math.floor(getAmount().doubleValue() * 10);
amount = amount / 10;
return new Money(this.getUnits(), new BigDecimal(amount));
}
/**
* 分进位为角
*/
public Money ceilCent() {
double amount = Math.ceil(getAmount().doubleValue() * 10);
amount = amount / 10;
return new Money(this.getUnits(), new BigDecimal(amount));
}
/**
* 分角进位为元
*/
public Money ceilChiao() {
double amount = Math.ceil(getAmount().doubleValue());
return new Money(this.getUnits(), new BigDecimal(amount));
}
protected BigDecimal computeRate(Currency another) {
BigDecimal rate = new BigDecimal("1.0");
//要求币种转换率精度都相同
if (!this.getUnits().equals(another)) {
// TODO 币种换算比率
}else{
rate = new BigDecimal("1.0");
}
return rate;
}
@Override
public Money clone() {
return new Money(this);
}
public int compareTo(Quantity<Currency> other) {
assert other instanceof Money : "Money不能同非Money类比较";
Money money = (Money) other;
BigDecimal difference = this.getAmount().multiply(computeRate(this.getUnits()))
.subtract(money.getAmount().multiply(computeRate(money.getUnits())));
if (difference.abs().setScale(DEFAULT_SCALE, RoundingMode.HALF_UP)
.multiply(new BigDecimal("100")).intValue() < 1)
return 0;
else
return difference.signum();
}
@Override
public boolean equals(Object other) {
if(!(other instanceof Money))
return false;
if (compareTo((Money)other) == 0)
return true;
else
return false;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getAmount().toPlainString());
return sb.toString();
}
}
public abstract class Quantity<T> extends BaseBean implements Serializable, Comparable<Quantity<T>> {
private static final long serialVersionUID = 7300915847975292623L;
private T units;
public Number amount;
protected Quantity() {
super();
}
public Quantity(T units, Number amount) {
assert units != null : "数量单位为空";
this.units = units;
this.amount = amount;
}
public Number getAmount() {
return amount;
}
public void setAmount(Number amount) {
Object oldAmount = this.amount;
this.amount = amount;
firePropertyChange("amount", oldAmount, amount);
}
public T getUnits() {
return units;
}
public void setUnits(T units) {
this.units = units;
}
/**
* 加
*/
public Quantity<T> plus(Quantity<T> another){
throw new UnsupportedOperationException("子类须实现该方法");
}
/**
* 减
*/
public Quantity<T> minus(Quantity<T> another){
throw new UnsupportedOperationException("子类须实现该方法");
}
/**
* 乘
*/
public Quantity<T> multiply(BigDecimal another) {
throw new UnsupportedOperationException("子类须实现该方法");
}
public Quantity<T> multiply(double another) {
throw new UnsupportedOperationException("子类须实现该方法");
}
/**
* 取负数
*/
public Quantity<T> negative() {
throw new UnsupportedOperationException("子类须实现该方法");
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object other) {
if (!(other instanceof Quantity))
return false;
Quantity<T> otherQuantity = (Quantity<T>) other;
return this.compareTo(otherQuantity) == 0;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getAmount());
sb.append(getUnits());
return sb.toString();
}
}
分享到:
相关推荐
在处理货币金额时,Joda-Money会抛出适当的异常,如`MoneyFormatException`(格式化错误)、`MoneyMismatchException`(货币类型不匹配)等,帮助开发者及时发现并处理问题。 ### 8. 结合其他库 Joda-Money可以与...
9. **扩展与自定义**:如果项目有特殊需求,laravel-money库允许开发者自定义货币类,扩展其功能,如添加新的货币类型或者实现特定的货币规则。 通过laravel-money,Laravel开发者可以轻松地在应用中处理各种货币...
在这个实现中,它可能是通过创建一个专门的Money类来封装货币值,并提供安全的货币操作方法。 **描述解析** "Money:一个Fowler货币模式的PHP实现" 描述进一步强调了这是一个PHP项目,它的主要目标是按照Fowler的...
本文将深入探讨如何使用C#语言来封装一个类,实现将金额转换为大写金额的功能,并通过具体的代码示例进行解析。 首先,我们需要创建一个名为`BigMoney`的类,这个类的主要任务是将输入的浮点数或字符串形式的金额...
1. 货币计算中的精度问题:由于浮点数在计算机中的表示存在误差,直接使用`double`或`float`类型进行货币计算可能导致精度损失。为了解决这个问题,Java提供了`BigDecimal`类,它可以精确表示任意大小的十进制数。...
闲置游戏(Idle Game)通常让玩家通过自动化的过程积累资源,即使在离线状态下也能继续发展,这种类型的游戏通常包含升级、投资和管理等元素,旨在提供一种轻松但有趣的方式来模拟财富增长。 标签为"JavaScript",...
总而言之,"dt-money:App Para Fluxo de Caixa-Rocketseat" 是一个利用 TypeScript 实现的现金流管理应用,通过学习这个项目,你可以深入理解 TypeScript 的核心特性,包括类型系统、模块、类与接口、函数以及异步...
总结来说,"money-frontend-elm"是一个基于Elm的前端项目,利用Elm的强类型、函数式特性和高效更新机制来构建可靠的金融应用。通过探索项目源码和学习Elm的相关知识,你将能更好地理解这个应用的工作原理,并可能...
首先,类是Java编程语言中的一种结构,它封装了数据(变量)和操作这些数据的方法。在这个"bankaccount"类中,我们有两个关键的变量: 1. `account`:代表银行账户的账号,通常为整数类型。 2. `leftmoney`:表示...
每个组件都封装了一部分 UI 和其逻辑,可以独立地渲染和更新。 2. **状态管理和 props**:React 通过 props 向组件传递数据,而状态管理则涉及如何在组件之间共享和更新数据。项目可能使用了 React 的内置状态管理...
### Module 03-面向对象编程 #### 面向对象编程概述 面向对象编程(Object-Oriented...**解析**:在第25行,尝试通过`A`类型的引用调用`y`方法,但`y`方法只存在于`B`类中,并不在接口`A`中声明,因此会导致编译错误。
在`setMoney`方法中,我们通过`isinstance`函数检查传入的值是否是整数类型,如果不是,则输出错误信息。 在Python中,使用`property`函数可以将上述的getter和setter方法转换为属性的访问方式,从而使得代码更加...
1. **基础语法**:Python的基础语法包括变量定义、数据类型(如整型、浮点型、字符串、列表、元组、字典和集合)、条件语句(if-else)、循环(for和while)、函数定义和调用、异常处理(try-except)等。...
Java是一种广泛使用的面向对象的编程语言,以其“一次编写,到处运行”的特性闻名,具有强大的跨平台能力,适用于开发各种类型的应用,包括桌面应用、Web应用和移动应用(尤其是Android平台)。 基于这些信息,我们...
deposit: 存款方法,参数类型:double, 返回类型:Account withdraw:取款方法,参数类型:double, 返回类型:Account 构造方法: 有参和无参,有参构造方法用于设置必要的属性 ATM 2:要求1:完成以下两种账户类型的...
面向对象编程(OOP)与面向过程编程不同,它强调将数据和操作数据的方法封装在一起,形成独立的对象,从而更好地模拟真实世界的实体。在Java中,面向对象主要体现在类、对象、实例以及封装、继承和多态这三个基本...