【java】小练习--零钱通
文章目录
- 前言
- 一、项目开发流程说明
- 二、功能实现
- 2.1 菜单
- 2.2 零钱通明细
- 2.3 零钱通收益
- 2.4 零钱通消费
- 2.5 零钱通退出确认
- 2.6 零钱通金额校验
- 2.7 完整代码
- 三、零钱通OOP版
前言
本文是我跟着B站韩顺平老师的 Java 教程学习时动手实现“零钱通”项目的学习笔记,主要用于记录自己的学习过程,方便复习和巩固
一、项目开发流程说明
- 项目需求说明
使用java开发零钱通项目,可以完成收益入账,消费,查看明细,退出系统等功能
- 项目界面
- 项目代码实现
编写文件 SmallChangeSys.java 完成基本功能(过程编程)
我们先使用过程编程,后面改成OOP版本
- 项目代码实现改进
在实现零钱通的基本功能后,我们还需要对项目代码进行改进,例如:
(1)用户输入4退出时,给出提示信息“你确定要退出吗?y/n”,必须输入正确的 y/n,否则循环输入指令,直到输入 y 或者 n
(2)在 收益入账 和 消费 时,判断金额是否合理,并给出相应的提示
(3)将面向过程的代码修改成面向对象的方法,编写 SmallChangeSysOOP.java类,并使用 SmallChangeSysApp.java 完成测试
二、功能实现
2.1 菜单
我们首先先完成 【显示菜单,并可以选择】
思路:
1)打印菜单,因为我们希望用户选择菜单的某个选项之后还可以继续选择其他选项,所以我们使用do-while将菜单包起来,并定义一个布尔类型的变量 loop,默认为true,作为循环的条件
2)打印菜单后,用户应该是可以选择选项的,所以我们需要定义Scanner,用Scanner对象来接收用户输入的数据,并用 String 类型的变量 key 用来接收用户输入的字符串
3)用户输入选择之后,我们需要判断用户的选择,并完成相应的功能。我们这里使用 switch-case
当用户输入“退出”的对应的选项后,需要退出循环,所以我们需要将 loop 变量的值改为 false
package smallchange;import java.util.Scanner;public class SmallChangeSys {//1.先完成显示菜单,并可以选择菜单,给出对应的提示public static void main(String[] args) {//定义相关变量boolean loop = true;Scanner scanner = new Scanner(System.in);String key = "";do{System.out.println("-------------零钱通菜单--------------");System.out.println("\t\t\t1 零钱通明细");System.out.println("\t\t\t2 收益入账");System.out.println("\t\t\t3 消费");System.out.println("\t\t\t4 退 出");System.out.print("请选择(1-4):");key = scanner.next();//使用 switch 分支控制switch (key) {case "1":System.out.println("显示零钱通明细");break;case "2":System.out.println("收益入账");break;case "3":System.out.println("消费");break;case "4":System.out.println("退出");loop = false;break;default:System.out.println("选择有误,请重新输入");}}while(loop);System.out.println("--------已退出零钱通项目---------");}
}
2.2 零钱通明细
接下来我们来完成零钱通明细,下面的三种方式都可以:
(1)可以把收益入账和消费,保存到数组
(2)可以使用对象
(3)可以使用String拼接
我们这里使用第三种方式
//在main方法中定义details变量
String details = "-------------零钱通明细--------------";//...
case "1":System.out.println(details);break;
2.3 零钱通收益
首先需要定义三个变量
- 接收入账的金额
- 入账的时间
- 余额
入账的时间我们这里用Date类型,但是由于默认的日期格式是国外的风格
所以我们还需要定义一个SimpleDateFormat对象,到时候用来把我们得到的日期格式化
double money = 0; // 入账金额
double balance = 0; // 余额
Date date = null; // date 是 java.util.Date类型,表示日期
double money = 0;SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 可以用于日期格式化
然后完成零钱通收益的功能
- 接收用户输入的入账金额并做检验(校验部分我们后面再实现)
- 获取当前日期
- 拼接到 details 字符串中
case "2":System.out.print("收益入账金额:");money = scanner.nextDouble();//money 的值范围应该校验//...balance += money;//拼接收益入账信息到 detailsdate = new Date(); // 获取当前日期details += "\n收益入账\t+" + money + "\t" + sdf.format(date) + "\t余额:" + balance;break;
2.4 零钱通消费
消费部分需要定义一个新变量,用来保存消费的原因
String note = "";
然后完成零钱通消费的功能
- 接收用户输入的消费金额和消费原因(校验部分我们后面再实现)
- 对用户输入的金额进行校验
- 获取当前日期
- 拼接到 details 字符串中
case "3":System.out.print("消费金额:");money = scanner.nextDouble();System.out.print("消费说明:");note = scanner.next();//money 的值范围应该校验//...balance -= money;date = new Date();details += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t余额:" + balance;break;
2.5 零钱通退出确认
用户输入 4 退出时,给出提示信息“你确定要退出吗?y/n”,必须输入正确的 y/n,否则循环输入指令,直到输入 y 或者 n
思路分析
(1)定义一个变量 choice
(2)使用 while(true) 无限循环,直到输入正确的 y 或 n 才break退出循环
(3)退出循环后,再判断 choice 是 y 还是 n ,就可以决定是否退出
case "4":
String choice = "";
while(true) { // 要求用户必须输入 y/n ,否则就一直循环System.out.println("你确定要退出吗?y/n");choice = scanner.next();if("y".equals(choice) || "n".equals(choice)) {break;}
}
//当用户退出while后,进行判断
if("y".equals(choice)) {loop = false;
}
break;
2.6 零钱通金额校验
在收益入账消费时,判断金额是否合理,并给出相应的提示
思路: 找出不正确的金额,然后给出提示
校验收益金额是否合理:
//输入收益金额后,校验金额
if(money <= 0) {System.out.println("收益入账失败,收益金额需要大于 0");break;
}
校验消费金额是否合理:
//输入消费金额后,校验金额
if(money <= 0 || money > balance) {System.out.println("你的消费金额应该在 0~" + balance);break;
}
2.7 完整代码
package smallchange;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;public class SmallChangeSys {//1.先完成显示菜单,并可以选择菜单,给出对应的提示public static void main(String[] args) {//定义相关变量boolean loop = true;Scanner scanner = new Scanner(System.in);String key = "";// 2.完成零钱通明细
// 三种方式都可以:
// (1)可以把收益入账和消费,保存到数组
// (2)可以使用对象
// (3)简单地话,可以使用String拼接String details = "----------------零钱通明细-----------------";//3.完成收益入账 完成功能驱动程序员增加新的变化和代码//思路:定义新变量double money = 0;double balance = 0;Date date = null; // date 是 java.util.Date类型,表示日期SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 可以用于日期格式化//4.消费//定义新变量,保存消费的原因String note = "";do{System.out.println("\n----------------零钱通菜单-----------------");System.out.println("\t\t\t1 零钱通明细");System.out.println("\t\t\t2 收益入账");System.out.println("\t\t\t3 消费");System.out.println("\t\t\t4 退 出");System.out.print("请选择(1-4):");key = scanner.next();//使用 switch 分支控制switch (key) {case "1":System.out.println(details);break;case "2":System.out.print("收益入账金额:");money = scanner.nextDouble();//money 的值范围应该校验//思路:找出不正确的金额,然后给出提示if(money <= 0) {System.out.println("收益入账失败,收益金额需要大于 0");break;}balance += money;//拼接收益入账信息到 detailsdate = new Date(); // 获取当前日期details += "\n收益入账\t+" + money + "\t" + sdf.format(date) + "\t余额:" + balance;break;case "3":System.out.print("消费金额:");money = scanner.nextDouble();System.out.print("消费说明:");note = scanner.next();//money 的值范围应该校验//思路:找出不正确的金额,然后给出提示if(money <= 0 || money > balance) {System.out.println("你的消费金额应该在 0~" + balance);break;}balance -= money;date = new Date();details += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t余额:" + balance;break;case "4"://用户输入 4 退出时,给出提示信息“你确定要退出吗?y/n”,//必须输入正确的 y/n,否则循环输入指令,直到输入 y 或者 n
// 思路
// (1)定义一个变量 choice
// (2)使用 while(true) 无限循环,直到输入正确的 y 或 n 才break退出循环
// (3)退出循环后,再判断 choice 是 y 还是 n ,就可以决定是否退出String choice = "";while(true) { // 要求用户必须输入 y/n ,否则就一直循环System.out.println("你确定要退出吗?y/n");choice = scanner.next();if("y".equals(choice) || "n".equals(choice)) {break;}}//当用户退出while后,进行判断if("y".equals(choice)) {loop = false;}break;default:System.out.println("选择有误,请重新输入");}}while(loop);System.out.println("--------已退出零钱通项目---------");}
}
三、零钱通OOP版
将面向过程的代码修改成面向对象的方法,编写 SmallChangeSysOOP.java类,并使用 SmallChangeSysApp.java 完成测试
SmallChangeSysOOP.java类主要用于完成零钱通的各个功能,而SmallChangeSysApp.java 通过调用SmallChangeSysOOP.java中的相关方法,使用零钱通的功能,二者关系如下:
SmallChangeSysOOP.java 类中代码如下:
package smallchange.oop;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;/*** 该类是完成零钱通的各个功能的类* 使用OOP(面向对象编程)* 将各个功能对应一个方法*/
public class smallChangeSysOOP {//属性boolean loop = true; // 循环条件Scanner scanner = new Scanner(System.in); // 接收用户输入String key = ""; // 用户的选择String details = "----------------零钱通明细-----------------";double money = 0; // 收益/消费的金额double balance = 0; // 余额Date date = null; // date 是 java.util.Date类型,表示日期SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 可以用于日期格式化String note = ""; // 消费的原因//完成显示菜单,并可以选择public void mainMenu() {do{System.out.println("\n----------------零钱通菜单-----------------");System.out.println("\t\t\t1 零钱通明细");System.out.println("\t\t\t2 收益入账");System.out.println("\t\t\t3 消费");System.out.println("\t\t\t4 退 出");System.out.print("请选择(1-4):");key = scanner.next();//使用 switch 分支控制switch (key) {case "1":this.detail();break;case "2":this.income();break;case "3":this.pay();break;case "4":this.exit();break;default:System.out.println("选择有误,请重新输入");}}while(loop);}//完成零钱通明细public void detail() {System.out.println(details);}//完成收益入账public void income() {System.out.print("收益入账金额:");money = scanner.nextDouble();//money 的值范围应该校验//思路:找出不正确的金额,然后给出提示if(money <= 0) {System.out.println("收益入账失败,收益金额需要大于 0");return;}balance += money;//拼接收益入账信息到 detailsdate = new Date(); // 获取当前日期details += "\n收益入账\t+" + money + "\t" + sdf.format(date) + "\t余额:" + balance;}//消费public void pay() {System.out.print("消费金额:");money = scanner.nextDouble();System.out.print("消费说明:");note = scanner.next();//money 的值范围应该校验//思路:找出不正确的金额,然后给出提示if(money <= 0 || money > balance) {System.out.println("你的消费金额应该在 0~" + balance);return;}balance -= money;date = new Date();details += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t余额:" + balance;}//退出public void exit() {String choice = "";while(true) { // 要求用户必须输入 y/n ,否则就一直循环System.out.println("你确定要退出吗?y/n");choice = scanner.next();if("y".equals(choice) || "n".equals(choice)) {break;}}//当用户退出while后,进行判断if("y".equals(choice)) {loop = false;}}
}
SmallChangeSysApp.java 中的代码如下
package smallchange.oop;/*** 这里我们直接调用 SmallChangeSysOOP 对象,显示主菜单即可*/
public class smallChangeSysApp {public static void main(String[] args) {smallChangeSysOOP smallChangeSysOOP = new smallChangeSysOOP();smallChangeSysOOP.mainMenu();}
}