|
本文参考:
《Java面向对象编程》,作者:孙卫琴
《漫画Java编程》,作者:孙卫琴,杜聚宾
网络书店需要处理所出售的各种书籍的信息。下面是一个网络书店展示卫琴姐创作的一本书的信息。
书名: 精通Spring:Java Web开发技术详解
定价: 89.9
作者: 孙卫琴
出版社: 清华大学出版社
ISBN: 9787302588337
出版时间: 2021年11月11日
页数: 392
是否在售: 是
Book类表示一本书,它具有name属性(书名)、price属性(价格)、author属性(作者)、publisher属性(出版社)、isbn属性(ISBN编号)、publishDate属性(出版日期)、pages属性(页数)、amount属性(销售总金额)。还有一个isSale属性,表示书是否正在出售,取值为true,表示正在出售,取值为false,表示停止出售。
Book类有一个用于销售当前书籍的sale(int quantity)方法:public void sale(int quantity){ //参数quantity表示销售数量
// 符号* 是乘法运算符
amount=amount+ price * quantity ; //累计书的销售总金额
} |
在Book类的程序入口main()方法中,创建一个表示上图所示的书的Book对象,再出售本书10000册,最后打印该书的书名和销售总金额。
为变量设定合理的数据类型Book类有多个属性,它们属于不同的数据类型。例如name属性为String类型,price属性和amount属性为double类型,pages属性为int类型,isSale属性为boolean类型,publishDate属性为java.util.Date类型。
在本范例中,sale(int quantity)方法会改变Book对象的amount属性的取值,这体现了Java对象的属性和方法的关系:属性表示对象的数据,而方法可以操纵对象的数据。
import java.util.Date;
import java.text.SimpleDateFormat;
public class Book{
String name; //表示书名
double price; //表示价格
String author; //书的作者
String publisher; //表示出版社
String isbn; //表示书的ISBN编号
Date publishDate; //表示出版日期
int pages; //表示书的页数
boolean isSale; //表示书是否正在出售
double amount; //表示书的销售总金额
……
public void sale(int quantity){ //参数quantity表示销售数量
amount=amount+ price* quantity ; //累计书的销售总金额
}
public static void main(String args[])throws Exception{
Book book=new Book();
book.name="精通Spring: Java Web开发技术详解";
book.price=89.9;
book.author="孙卫琴";
book.publisher="清华大学出版社";
book.isbn="9787302588337";
book.pages=392;
book.isSale=true;
book.amount=0;
SimpleDateFormat df =
new SimpleDateFormat("yyyy-MM-dd");
//根据指定的日期格式返回一个表示2021年11月1日的Date对象
Date publishDate = df.parse("2021-11-01");
book.publishDate=publishDate;
book.sale(10000); //销售10000册书
System.out.println(book.name
+"的销售总金额:"+book.amount) ;
}
} |
Book类引用了java.util.Date类和java.text.SimpleDateFormat类,因此需要通过import语句将这两个类引入。
创建表示日期的Date对象在Book类的main()方法中,以下代码创建了一个表示2021年11月1日的Date对象:
//指定日期格式
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//根据指定的日期格式返回一个表示2021年11月1日的Date对象
Date publishDate = df.parse("2021-11-01"); |
以上代码首先创建了一个表示具体日期格式“yyyy-MM-dd”的SimpleDateFormat对象,接下来调用这个对象的parse()方法,对字符串“2021-11-01”进行解析,把它转换为表示日期的Date对象。
格式化输出浮点数在打印浮点类型数据时,如果希望只保留两位小数,可以利用String类的静态format(String fmt, Object... args)方法来设定数据格式,第一个参数fmt指定数据格式,第二个参数args指定待格式化的数据。
在以下代码中,format()方法的第一个参数“%.2f”指定数据格式,表示保留两位小数,第二个参数book.amount就是需要进行格式化的数据:
//保留总金额的两位小数
String amountDisplay=String.format("%.2f",book.amount);
System.out.println(book.name
+"的销售总金额:"+amountDisplay) ; |
假定book.ammout的取值为15600.983,那么amountDisplay变量的值为“15600.98”。
浮点数的运算精度在Book类中,price变量和amount变量是double类型。值得注意的是,如果对这种变量进行数学运算,不能保证得到精确的运算结果。例如在以下代码中,price变量表示一本书的单价,quanity变量表示销售册数,表达式“price*quantity”把这两个变量相乘,计算销售总额:
double price =4.015; //书的单价
int quantity=100; //销售数量
//打印401.49999999999994
System.out.println(price*quantity); |
表达式“price*quantity”的运算结果为401.49999999999994,而不是预期的401.5。为什么会得到不精确的运算结果呢?这是因为在内存中,只能用二进制数据来表示各种类型的数据,例如用“00000011”来表示byte类型的数据3,用“00000000 00000000 00000000 00000011”表示int类型的数据3。那么,double类型的数据4.015在内存中如何表示呢?在内存中是采用二进制的科学计数法来表示小数的,这种方式无法精确地表示每个小数,只能提供一个非常接近小数的数值。当double类型的数据参与加减乘除这样的数学运算时,就可能导致不精确的运算结果。
在金融领域和商业领域,要求数学运算具有可靠的精确性,该如何实现呢?可以使用Java类库中的java.math.BigDecimal类。BigDecimal类支持对浮点数进行精确的数学运算。BigDecimal类包括以下方法:
add(BigDecimal b):进行精确的加法运算。
subtract(BigDecimal b) :进行精确的减法运算。
multiply(BigDecimal b) :进行精确的乘法运算。
divide(BigDecimal b, int scale,RoundingMode more) :进行除法运算,参数scale指定需要精确到小数点以后几位。参数mode
指定小数部分的舍入模式,如果取值为BigDecimal.ROUND_HALF_UP,表示采用四舍五入模式。
以下代码利用BigDecimal类来计算销售总额,得到了预期精度的运算结果:
double price =4.015; //书的单价
int quantity=100; //销售数量
//创建表示单价的BigDecimal对象
BigDecimal priceBig =
new BigDecimal(Double.toString(price));
//创建表示销售数量的BigDecimal对象
BigDecimal quantityBig =
new BigDecimal(Double.toString(quantity));
//进行乘法运算
BigDecimal amountBig=priceBig.multiply(quantityBig);
//获得BigDecimal对象包装的double类型数据
double amount=amountBig.doubleValue();
System.out.println(amount); //打印401.5 |
程序猿的技术大观园:www.javathinker.net
|
|