`

Money类型的封装

UP 
阅读更多

 

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-用于表示货币金额的Java库

    在处理货币金额时,Joda-Money会抛出适当的异常,如`MoneyFormatException`(格式化错误)、`MoneyMismatchException`(货币类型不匹配)等,帮助开发者及时发现并处理问题。 ### 8. 结合其他库 Joda-Money可以与...

    Laravel开发-laravel-money

    9. **扩展与自定义**:如果项目有特殊需求,laravel-money库允许开发者自定义货币类,扩展其功能,如添加新的货币类型或者实现特定的货币规则。 通过laravel-money,Laravel开发者可以轻松地在应用中处理各种货币...

    Money一个Fowler货币模式的PHP实现

    在这个实现中,它可能是通过创建一个专门的Money类来封装货币值,并提供安全的货币操作方法。 **描述解析** "Money:一个Fowler货币模式的PHP实现" 描述进一步强调了这是一个PHP项目,它的主要目标是按照Fowler的...

    将金额转换成大写金额 封装类 及 例子

    本文将深入探讨如何使用C#语言来封装一个类,实现将金额转换为大写金额的功能,并通过具体的代码示例进行解析。 首先,我们需要创建一个名为`BigMoney`的类,这个类的主要任务是将输入的浮点数或字符串形式的金额...

    java代码-实验报告Money

    1. 货币计算中的精度问题:由于浮点数在计算机中的表示存在误差,直接使用`double`或`float`类型进行货币计算可能导致精度损失。为了解决这个问题,Java提供了`BigDecimal`类,它可以精确表示任意大小的十进制数。...

    MakeMoney:赚钱是一种闲置游戏。 '纳夫说

    闲置游戏(Idle Game)通常让玩家通过自动化的过程积累资源,即使在离线状态下也能继续发展,这种类型的游戏通常包含升级、投资和管理等元素,旨在提供一种轻松但有趣的方式来模拟财富增长。 标签为"JavaScript",...

    dt-money:App Para Fluxo de Caixa-Rocketseat

    总而言之,"dt-money:App Para Fluxo de Caixa-Rocketseat" 是一个利用 TypeScript 实现的现金流管理应用,通过学习这个项目,你可以深入理解 TypeScript 的核心特性,包括类型系统、模块、类与接口、函数以及异步...

    money-frontend-elm

    总结来说,"money-frontend-elm"是一个基于Elm的前端项目,利用Elm的强类型、函数式特性和高效更新机制来构建可靠的金融应用。通过探索项目源码和学习Elm的相关知识,你将能更好地理解这个应用的工作原理,并可能...

    类实现银行帐户

    首先,类是Java编程语言中的一种结构,它封装了数据(变量)和操作这些数据的方法。在这个"bankaccount"类中,我们有两个关键的变量: 1. `account`:代表银行账户的账号,通常为整数类型。 2. `leftmoney`:表示...

    ignite-dt-money

    每个组件都封装了一部分 UI 和其逻辑,可以独立地渲染和更新。 2. **状态管理和 props**:React 通过 props 向组件传递数据,而状态管理则涉及如何在组件之间共享和更新数据。项目可能使用了 React 的内置状态管理...

    Module 03-面向对象编程

    ### Module 03-面向对象编程 #### 面向对象编程概述 面向对象编程(Object-Oriented...**解析**:在第25行,尝试通过`A`类型的引用调用`y`方法,但`y`方法只存在于`B`类中,并不在接口`A`中声明,因此会导致编译错误。

    Python属性和内建属性实例解析

    在`setMoney`方法中,我们通过`isinstance`函数检查传入的值是否是整数类型,如果不是,则输出错误信息。 在Python中,使用`property`函数可以将上述的getter和setter方法转换为属性的访问方式,从而使得代码更加...

    Python代码复习合集.rar

    1. **基础语法**:Python的基础语法包括变量定义、数据类型(如整型、浮点型、字符串、列表、元组、字典和集合)、条件语句(if-else)、循环(for和while)、函数定义和调用、异常处理(try-except)等。...

    money-money-go-my-home:嘛咪嘛咪哄,钱都到我钱包来

    Java是一种广泛使用的面向对象的编程语言,以其“一次编写,到处运行”的特性闻名,具有强大的跨平台能力,适用于开发各种类型的应用,包括桌面应用、Web应用和移动应用(尤其是Android平台)。 基于这些信息,我们...

    (java se 代码)Bank Account Management System 银行账户管理子系统

    deposit: 存款方法,参数类型:double, 返回类型:Account withdraw:取款方法,参数类型:double, 返回类型:Account 构造方法: 有参和无参,有参构造方法用于设置必要的属性 ATM 2:要求1:完成以下两种账户类型的...

    java面向对象,java面向对象

    面向对象编程(OOP)与面向过程编程不同,它强调将数据和操作数据的方法封装在一起,形成独立的对象,从而更好地模拟真实世界的实体。在Java中,面向对象主要体现在类、对象、实例以及封装、继承和多态这三个基本...

Global site tag (gtag.js) - Google Analytics