【java】小练习--零钱通

news2025/5/25 6:23:11

文章目录

  • 前言
  • 一、项目开发流程说明
  • 二、功能实现
    • 2.1 菜单
    • 2.2 零钱通明细
    • 2.3 零钱通收益
    • 2.4 零钱通消费
    • 2.5 零钱通退出确认
    • 2.6 零钱通金额校验
    • 2.7 完整代码
  • 三、零钱通OOP版

前言

本文是我跟着B站韩顺平老师的 Java 教程学习时动手实现“零钱通”项目的学习笔记,主要用于记录自己的学习过程,方便复习和巩固

一、项目开发流程说明

  1. 项目需求说明

使用java开发零钱通项目,可以完成收益入账,消费,查看明细,退出系统等功能

  1. 项目界面

在这里插入图片描述

  1. 项目代码实现

编写文件 SmallChangeSys.java 完成基本功能(过程编程)

我们先使用过程编程,后面改成OOP版本

  1. 项目代码实现改进

在实现零钱通的基本功能后,我们还需要对项目代码进行改进,例如:

(1)用户输入4退出时,给出提示信息“你确定要退出吗?y/n”,必须输入正确的 y/n,否则循环输入指令,直到输入 y 或者 n

(2)在 收益入账 和 消费 时,判断金额是否合理,并给出相应的提示

(3)将面向过程的代码修改成面向对象的方法,编写 SmallChangeSysOOP.java类,并使用 SmallChangeSysApp.java 完成测试

二、功能实现

2.1 菜单

我们首先先完成 【显示菜单,并可以选择】

img

思路:

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 零钱通收益

img

首先需要定义三个变量

  1. 接收入账的金额
  2. 入账的时间
  3. 余额

入账的时间我们这里用Date类型,但是由于默认的日期格式是国外的风格

img

所以我们还需要定义一个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"); // 可以用于日期格式化

然后完成零钱通收益的功能

  1. 接收用户输入的入账金额并做检验(校验部分我们后面再实现)
  2. 获取当前日期
  3. 拼接到 details 字符串中
case "2":
    System.out.print("收益入账金额:");
    money = scanner.nextDouble();
    //money 的值范围应该校验
    //...
    balance += money;
    //拼接收益入账信息到 details
    date = new Date(); // 获取当前日期
    details += "\n收益入账\t+" + money + "\t" + sdf.format(date) + "\t余额:" + balance;
    break;

2.4 零钱通消费

消费部分需要定义一个新变量,用来保存消费的原因

String note = "";

然后完成零钱通消费的功能

  1. 接收用户输入的消费金额和消费原因(校验部分我们后面再实现)
  2. 对用户输入的金额进行校验
  3. 获取当前日期
  4. 拼接到 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;
                    //拼接收益入账信息到 details
                    date = 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中的相关方法,使用零钱通的功能,二者关系如下:

img

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;
        //拼接收益入账信息到 details
        date = 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();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2385143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker-mongodb

拉取 MongoDB 镜像: docker pull mongo 创建容器并设置用户&#xff1a; 要挂载本地数据目录&#xff0c;请替换此路径: /Users/Allen/Env/AllenDocker/mongodb/data/db docker run -d --name local-mongodb \-e MONGO_INITDB_ROOT_USERNAMEadmin \-e MONGO_INITDB_ROOT_PA…

Gartner《Optimize GenAI Strategy for 4 Key ConsumerMindsets》学习心得

一、引言 在当今数字化营销浪潮中,生成式人工智能(GenAI)正以前所未有的速度重塑着市场格局。GenAI 既是一场充满机遇的变革,也是一场潜在风险的挑战。一方面,绝大多数 B2C 营销领导者对 GenAI 赋能营销抱有极高期待,他们看到了 GenAI 在提升时间与成本效率方面的巨大潜…

达梦数据库-学习-22-库级物理备份恢复(超详细版)

目录 一、环境信息 二、说点什么 三、概念 1、备份恢复 2、重做日志 3、归档日志 4、LSN 5、检查点 四、语法 1、BACKUP DATABASE 2、DMRMAN RESTORE DATABASE 3、DMRMAN RECOVER DATABASE 4、DMRMAN UPDATE DB_MAGIC 五、实验 1、开归档 &#xff08;1&#xf…

python网络爬虫的基本使用

各位帅哥美女点点关注&#xff0c;有关注才有动力啊 网络爬虫 引言 我们平时都说Python爬虫&#xff0c;其实这里可能有个误解&#xff0c;爬虫并不是Python独有的&#xff0c;可以做爬虫的语言有很多例如&#xff1a;PHP、JAVA、C#、C、Python。 为什么Python的爬虫技术会…

AI Agent开发第74课-解构AI伪需求的魔幻现实主义

开篇 🚀在之前的系列中我们狂炫了AI Agent的各种高端操作(向量数据库联动、多模态感知、动态工作流等…),仿佛每个程序员都能用LLM魔法点石成金✨。 但今天咱们要泼一盆透心凉的冷水——当企业把AI当成万能胶水强行粘合所有需求时,连电风扇都能被玩出量子纠缠的魔幻现实…

【卫星通信】通信卫星链路预算计算及其在3GPP NTN中的应用

引言 卫星通信是现代信息传播的重要手段&#xff0c;广泛应用于电信、广播、气象监测、导航等领域。卫星链路预算计算是设计和优化卫星通信系统的重要步骤&#xff0c;它帮助工程师评估信号在传输过程中的衰减和增益&#xff0c;从而确保系统在预定条件下可靠地工作。 1. 链路…

c++命名空间的作用及命名改编

c命名空间的作用及命名改编 命名空间 namespace的作用&#xff1a; std::命名空间&#xff0c;命名空间&#xff08;namespace&#xff09;是 C 中用于解决标识符命名冲突问题的机制。在大型程序开发中&#xff0c;不同模块可能会使用相同名称的变量、函数或类等标识符&…

echarts实现项目进度甘特图

描述 echarts并无甘特图配置项&#xff0c;我们可以使用柱状图模拟&#xff0c;具体配置项如下&#xff0c;可以在echarts直接运行 var option {backgroundColor: "#fff",legend: {data: ["计划时间","实际时间"],align: "right",…

2025深圳国际无人机展深度解析:看点、厂商与创新亮点

2025深圳国际无人机展深度解析&#xff1a;看点、厂商与创新亮点 1.背景2.核心看点&#xff1a;技术突破与场景创新2.1 eVTOL&#xff08;飞行汽车&#xff09;的规模化展示2.2 智能无人机与无人值守平台2.3 新材料与核心零部件革新2.4 动态演示与赛事活动 3.头部无人机厂商4.核…

人形机器人通过观看视频学习人类动作的技术可行性与前景展望

摘要 本文深入探讨人形机器人通过观看视频学习人类动作这一技术路线的正确性与深远潜力。首先阐述该技术路线在模仿人类学习过程方面的优势&#xff0c;包括对人类动作、表情、发音及情感模仿的可行性与实现路径。接着从技术原理、大数据训练基础、与人类学习速度对比等角度论证…

第三十四天打卡

DAY 34 GPU训练及类的call方法 知识点回归&#xff1a; CPU性能的查看&#xff1a;看架构代际、核心数、线程数 GPU性能的查看&#xff1a;看显存、看级别、看架构代际 GPU训练的方法&#xff1a;数据和模型移动到GPU device上 类的call方法&#xff1a;为什么定义前向传播时可…

配置tomcat时,无法部署工件该怎么办?

当我们第一次在IDEA中创建Java项目时&#xff0c;配置tomcat可能会出现无法部署工件的情况&#xff0c;如图&#xff1a; 而正常情况应该是&#xff1a; 那么该如何解决呢&#xff1f; 步骤一 点开右上角该图标&#xff0c;会弹出如图页面 步骤二 步骤三 步骤四

.NET外挂系列:8. harmony 的IL编织 Transpiler

一&#xff1a;背景 1. 讲故事 前面文章所介绍的一些注入技术都是以方法为原子单位&#xff0c;但在一些罕见的场合中&#xff0c;这种方法粒度又太大了&#xff0c;能不能以语句为单位&#xff0c;那这个就是我们这篇介绍的 Transpiler&#xff0c;它可以修改方法的 IL 代码…

基于netty实现视频流式传输和多线程传输

文章目录 业务描述业务难点流式传输客户端(以tcp为例)服务端测试类测试步骤多线程传输客户端服务端测试类测试步骤多线程流式传输总结业务描述 多台终端设备持续给数据服务器(外)发送视频数据,数据服务器(外)通过HTTP协议将数据经过某安全平台转到数据服务器(内),数据…

全面指南:使用Node.js和Python连接与操作MongoDB

在现代Web开发中&#xff0c;数据库是存储和管理数据的核心组件。MongoDB作为一款流行的NoSQL数据库&#xff0c;以其灵活的数据模型、高性能和易扩展性广受开发者欢迎。无论是使用Node.js还是Python&#xff0c;MongoDB都提供了强大的官方驱动和第三方库&#xff0c;使得数据库…

游戏引擎学习第308天:调试循环检测

回顾并为今天的内容做准备 我们正在进行游戏开发中的精灵&#xff08;sprite&#xff09;排序工作&#xff0c;虽然目前的实现已经有了一些改进&#xff0c;情况也在逐步好转&#xff0c;我们已经实现了一个图结构的排序算法&#xff0c;用来处理精灵渲染顺序的问题。然而&…

WPF性能优化之延迟加载(解决页面卡顿问题)

文章目录 前言一. 基础知识回顾二. 问题分析三. 解决方案1. 新建一个名为DeferredContentHost的控件。2. 在DeferredContentHost控件中定义一个名为Content的object类型的依赖属性&#xff0c;用于承载要加载的子控件。3. 在DeferredContentHost控件中定义一个名为Skeleton的ob…

移植 FART 到 Android 10 实现自动化脱壳

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ FART 源码 FART 是 ART 环境下基于主动调用的自动化脱壳方案。 关于 FART 详细介绍参考&#xff1a; FART 自动化脱壳框架简介与脱壳点的选择 FART 主动调用…

COMPUTEX 2025 | 广和通创新解决方案共筑AI交互新纪元

5月20日至23日&#xff0c;广和通携多领域创新解决方案亮相2025年台北国际电脑展&#xff08;COMPUTEX 2025&#xff09;&#xff0c;台北南港展览馆#K0727a展位。此次展会&#xff0c;广和通围绕“Advancing Connectivity Intelligent Future”为主题&#xff0c;设置四大核心…

了解Android studio 初学者零基础推荐(3)

kotlin中的数据类及对象 使用泛型创建可重复使用的类 我们将常在线答题考试&#xff0c;有的考试题型包括判断&#xff0c;或者填空&#xff0c;以及数学题&#xff0c;此外试题内容还包括难易程度&#xff1a;"easy”,"medium"&#xff0c;"hard",…