1.JAVA小项目(零钱通)

一、说明

博客内容:B站韩顺平老师的视频,以及代码的整理。此项目分为两个版本:

  1. 面向过程思路实现
  2. 面向对象思路实现
    韩老师视频地址:【【零基础 快速学Java】韩顺平 零基础30天学会Java】 https://www.bilibili.com/video/BV1fh411y7R8/?p=342&share_source=copy_web&vd_source=656bca56998f14127313f0283f22ac0a
    【注意】:仅限学习,如有侵权,请联系本人删除。

项目实现–面向过程思路

先贴代码,项目的完整代码如下:

package smallchange;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/**
 * @author cdj
 * @Version1.0
 */
public class SmallChangeSys {

    // 1. 先完成显示菜单,并可以选择菜单,给出对应提示
    // 2. 完成零钱通明细
    // 3. 完成收益入账
    // 4. 完成消费
    // 5. 退出
    // 6. 用户输入4退出时,给出提示”你要退出吗? y/n“,必须要正确的输入y/n,否则循环输入指令,直到输入y 或者 n
    // 7. 在收益入账和消费时,判断金额是否合理,并给出相应的提示

    public static void main(String[] args) {

        // 定义相关的变量
        boolean loop = true;
        Scanner sc = new Scanner(System.in);
        String key = "";

        // 2.完成零钱通明细
        // (1) 可以把收益入账和消费,保存到数组 (2)可以使用对象 (3)简单的会可以使用String拼接
        String detils = "------------------零钱通明细--------------------";

        // 3. 完成收益入账,完成功能驱动程序员增加新的变化和代码
        // 定义新的变量
        double money = 0;
        double balance = 0;
        Date date = null;   // data 是 java.util.Data类型,表示日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");    // 可以用于日期格式化的

        // 4. 消费
        // 定义新的变量,保存消费的原因
        String note = null;


        do{

            System.out.println("\n===================零钱通菜单================");
            System.out.println("\t\t\t\t\t1 零钱通明细");
            System.out.println("\t\t\t\t\t2 收益入账");
            System.out.println("\t\t\t\t\t3 消费");
            System.out.println("\t\t\t\t\t4 退             出");

            System.out.print("请选择(1-4): ");
            key = sc.nextLine();

            // 使用 switch 分支控制
            switch (key){
                case "1":
                    System.out.println(detils);
                    break;
                case "2":
                    System.out.print("收益入账金额:");
                    money = sc.nextDouble();
                    // 清空输入缓冲区
                    sc.nextLine();
                    // money 的值应该校验
                    // 找出不正确的金额条件,然后给出提示,就直接break
                    if(money <= 0){
                        System.out.println("收益入账金额需要大于0");
                        break;
                    }
                    balance += money;
                    // 获取当前日期
                    date = new Date();
                    // 拼接收益入账信息到details
                    detils += "\n收益入账\t" + money + "\t" + sdf.format(date) + "\t" + balance;
                    break;

                case "3":
                    System.out.print("收益消费金额:");
                    money = sc.nextDouble();
                    sc.nextLine();  // 清空输入缓冲区
                    // money 的值应该校验 TODO
                    // 找出金额不正确的情况
                    if(money <= 0 || money > balance){
                        System.out.println("你的消费金额应该在 0-" + balance);
                        break;
                    }
                    System.out.print("消费说明: ");
                    note = sc.next();
                    sc.nextLine();
                    balance -= money;
                    // 拼接消费信息到details
                    date = new Date(); // 获取到当前时间
                    detils += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t" + balance;
                    break;
                case "4":
                    // 用户输入4退出时,给出提示”你要退出吗? y/n“,必须要正确的输入y/n
                    // (1) 定义一个变量 choice,接收用户的输入
                    // (2) 使用 while + break,来处理接收的输入时 y 或者 n
                    // (3) 退出while后,再判断choice是y还是n,就可以决定是否退出。
                    // (4) 建议一段代码完成一个小功能,尽量不要混在一起
                    String choice = "";
                    while (true) {  // 要求用户必须输入 y/n,否则就一直循环
                        System.out.println("你确定要退出吗? y/n");
                        choice = sc.nextLine();
                        if ("y".equals(choice) || "n".equals(choice)) {
                            break;
                        }
                    }
                    // 当用户退出后,再进行判断
                    if (choice.equals("y")) {
                        loop = false;
                    }
                    break;
                default:
                    System.out.println("选择有误,请重新选择");
            }

        }while(loop);

        System.out.println("------------------退出了零钱通项目------------------");
    }
}

代码思路

先看一下项目需求(资料来源:【【零基础 快速学Java】韩顺平 零基础30天学会Java】 https://www.bilibili.com/video/BV1fh411y7R8/?p=335&share_source=copy_web&vd_source=656bca56998f14127313f0283f22ac0a)
在这里插入图片描述
首先先理一下需要完成的几个功能:

  1. 界面显示
  2. 零钱通明细
  3. 收益入账
  4. 消费
  5. 退出

将这几个功能分别完成(一个代码块只实现一个功能)

1.界面显示

在界面显示的时候,我们需要完成的任务有以下两个:

  • (1) 完成显示菜单
  • (2) 可以选择菜单,并给出对应提示
    关于任务(1),我们可以考虑直接使用Println语句将菜单打印出来:
 System.out.println("\n===================零钱通菜单================");
            System.out.println("\t\t\t\t\t1 零钱通明细");
            System.out.println("\t\t\t\t\t2 收益入账");
            System.out.println("\t\t\t\t\t3 消费");
            System.out.println("\t\t\t\t\t4 退             出");

实现了任务(1)之后,我们需要考虑的就是如何使得我们可以根据提示进行选择。那我们就需要去思考,哪个语句可以提供选择功能,很自然的想到了switch语句。先看一下switch语句的语法:

switch (expression) {
    case value1:
        // 当 expression 的值等于 value1 时执行这里的代码
        // 可以有多行代码
        break;
    case value2:
        // 当 expression 的值等于 value2 时执行这里的代码
        // 可以有多行代码
        break;
    // 可以有更多的 case 语句
    default:
        // 当 expression 的值与所有 case 不匹配时执行这里的代码
}

switch语法可以得出:我们需要定义一个expression让我们去选择哪条case语句。根据菜单给的提示,我们选择定义一个String类型的变量,去存储我们的选择。由于我们需要去输入我们的选择,那我们就需要一个输入的功能Scanner
由以上分析,我们就可以搭建一个程序框架:

public class SmallChangeSys {

    // 1. 先完成显示菜单,并可以选择菜单,给出对应提示
    public static void main(String[] args) {

        // 定义相关的变量
        Scanner sc = new Scanner(System.in);
        String key = "";

        System.out.println("\n===================零钱通菜单================");
        System.out.println("\t\t\t\t\t1 零钱通明细");
        System.out.println("\t\t\t\t\t2 收益入账");
        System.out.println("\t\t\t\t\t3 消费");
        System.out.println("\t\t\t\t\t4 退             出");

        System.out.print("请选择(1-4): ");
        key = sc.nextLine();

        // 使用 switch 分支控制
        switch (key){
            case "1":
				// TODO
                break;
            case "2":
                // TODO
                break;
            case "3":
            	// TODO
                break;
            case "4":
            	// TODO
                break;
            default:
            	// TODO
                break;
    }
}

上述代码能让我们完成任务(1)和任务(2),但是它只能执行一次,选择一个功能。我们需要多次执行,而且考虑到不管什么情况,都会执行一次。那就想到do while。先看一下do while的语法:

do {
    // 循环体代码块
} while (condition);

while 关键字后面跟着一个循环条件。只要循环条件为 true,循环将继续执行;否则循环终止。为了使我们退出循环的时候方便,这里我们选择定义一个bool类型的变量loop。当我们需要退出时,只需要将它置为false即可。将上述代码修改:

public class SmallChangeSys {

    // 1. 先完成显示菜单,并可以选择菜单,给出对应提示
    public static void main(String[] args) {

        // 定义相关的变量
        Scanner sc = new Scanner(System.in);
        String key = "";
        boolean loop = true;

		do {
		
			System.out.println("\n===============零钱通菜单==============");
	        System.out.println("\t\t\t\t\t1 零钱通明细");
	        System.out.println("\t\t\t\t\t2 收益入账");
	        System.out.println("\t\t\t\t\t3 消费");
	        System.out.println("\t\t\t\t\t4 退出");

	        System.out.print("请选择(1-4): ");
	        key = sc.nextLine();
	        
				 // 使用 switch 分支控制
	        switch (key){
	            case "1":
	            	// 零钱通明细
					// TODO
	                break;
	            case "2":
	            	// 收益入账
	                // TODO
	                break;
	            case "3":
	            	// 消费
	            	// TODO
	                break;
	            case "4":
	            	// 退出
	            	// TODO
	                break;
	            default:
	            	// TODO
	                break;
			}while (loop)   
    }
}

这样,整个程序的框架就已经搭建好了。下面使用代码块分别实现各个功能。

2. 零钱通明细

我们需要实现下图功能,那我们就需要一个变量进行显示。实现的方式有三种

  1. 把收入入账和消费,保存到数组(数组扩容比较麻烦)
  2. 使用对象
  3. 使用String拼接
    此处考虑使用String进行拼接,所以需要定义一个String类型的变量:
String detils = "------------------零钱通明细--------------------";

在定义完变量后,我们需要把它放入菜单的选择中(case1),当我们需要查看明细时,只需要将这个字符串打印出来即可(在后续操作过程中有可能会修改字符串)。

case "1":
	System.out.println(detils);
	break;

在这里插入图片描述

3.收益入账

首先需要一个变量用来存储收益,所以先定义一个存储收益的变量money:

double money = 0;

我们的代码中已经有一个sc用于交互,所以money的值可以直接由我们输入。但是在编写代码过程中我发现如果没有清除缓存的话,代码会直接跳转到switch中的defalut语句,所以在输入money加入了一个清理缓存的语句:

money = sc.nextDouble();
sc.nextLine();  // 清空输入缓冲区

当我们有收益时,我们的余额也会发生改变,所以此处我们添加一个存储余额的变量balacnce:

double balance = 0;

有了balance用来存储余额,在实现收益功能的代码块中,自然balance += money。再看一下打印的信息里面还有一个data信息,所以需要添加时间相关的信息:

Date date = null;   // data 是 java.util.Data类型,表示日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");    // 可以用于日期格式化的
date = new Date();

因为我们用的时String进行的拼接,那么现在要将新增的记录拼接到我们的details中:

// 拼接收益入账信息到details
detils += "\n收益入账\t" + money + "\t" + sdf.format(date) + "\t" + balance;

注意看拼接的过程中是先拼接了一个\n,所以无论最终我们的details有多长,它都只是一个变量。
最终收益入账功能实现的代码如下:

case "2":
	 System.out.print("收益入账金额:");
	 money = sc.nextDouble();
	 // 清空输入缓冲区
	 sc.nextLine();
	 // money 的值应该校验
	 // 找出不正确的金额条件,然后给出提示,就直接break
	 if(money <= 0){
	     System.out.println("收益入账金额需要大于0");
	     break;
	 }
	 balance += money;
	 // 获取当前日期
	 date = new Date();
	 // 拼接收益入账信息到details
	 detils += "\n收益入账\t" + money + "\t" + sdf.format(date) + "\t" + balance;
	 break;

除去上述将的内容,在其中还添加了检验money值得功能。
其它功能实现方式和上述方式大同小异,此处就不再进行书写。

总结

在项目实现过程中,首先是分析项目的需求,然后根据项目的需求将整个代码的框架搭建出来。在搭建过程中,遵循每个代码块实现一个功能,并且在需要什么变量的时候就定义什么变量(根据实际需求去定义变量)。在听课过程中,韩老师给的两个建议是十分重要的:

  1. 一段代码完成一个小功能,不要混在一起。
  2. 找出不正确的条件用来判断,而不是找正确的条件。

项目实现–面向对象思路

先贴代码,分为两个文件

  1. SmallChangeSysOOP:实现各种功能
  2. SmallChangeSysAPP:调用
    SmallChangeSysOPP代码如下:
package smallchange.oop;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/**
 * @author cdj
 * @Version1.0
 * 完成零钱通的各个功能
 * 将各个功能对应一个方法
 */
public class SmallChangeSysOOP {

    // 属性
    boolean loop = true;
    Scanner sc = new Scanner(System.in);
    String key = "";
    String detils = "------------------零钱通明细---------------";
    double money = 0;
    double balance = 0;
    Date date = null;   // data 是 java.util.Data类型,表示日期
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");    // 可以用于日期格式化的
    String note = null;

    // 显示菜单,并可以选择
    public void mainMenu() {

        do{
            System.out.println("\n===================零钱通菜单================");
            System.out.println("\t\t\t\t\t1 零钱通明细");
            System.out.println("\t\t\t\t\t2 收益入账");
            System.out.println("\t\t\t\t\t3 消费");
            System.out.println("\t\t\t\t\t4 退             出");

            System.out.print("请选择(1-4): ");
            key = sc.nextLine();

            // 使用 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(detils);
    }

    // 完成收益入账
    public void income() {
        System.out.print("收益入账金额:");
        money = sc.nextDouble();
        // 清空输入缓冲区
        sc.nextLine();
        // money 的值应该校验
        // 找出不正确的金额条件,然后给出提示,就直接break
        if(money <= 0){
            System.out.println("收益入账金额需要大于0");
            return; // 退出方法,不再执行后面的方法
        }
        balance += money;
        // 获取当前日期
        date = new Date();
        // 拼接收益入账信息到details
        detils += "\n收益入账\t" + money + "\t" + sdf.format(date) + "\t" + balance;
    }

    // 消费
    public void pay() {
        System.out.print("收益消费金额:");
        money = sc.nextDouble();
        sc.nextLine();  // 清空输入缓冲区
        // money 的值应该校验 TODO
        // 找出金额不正确的情况
        if(money <= 0 || money > balance){
            System.out.println("你的消费金额应该在 0-" + balance);
            return;
        }
        System.out.print("消费说明: ");
        note = sc.next();
        sc.nextLine();
        balance -= money;
        // 拼接消费信息到details
        date = new Date(); // 获取到当前时间
        detils += "\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 = sc.nextLine();
            if ("y".equals(choice) || "n".equals(choice)) {
                break;
            }
        }
        // 当用户退出后,再进行判断
        if (choice.equals("y")) {
            loop = false;
            System.out.println("------------------退出了零钱通项目------------------");
        }
    }
}

SmallChangeSysAPP代码如下:

package smallchange.oop;

/**
 * @author cdj
 * @Version1.0
 * 调用SmallChangeSysOOP 对象
 */
public class SmallChangeSysAPP {
    public static void main(String[] args) {
        new SmallChangeSysOOP().mainMenu();
    }
}

在Structure(使用alt+7打开)界面下可以查看OOP类下面的属性和方法:
在这里插入图片描述
将其中的各个功能封装进OOP类下面的方法中,后续我们只用调用它的方法就可以了。对于其它人想用我们的代码,或者说后续添加方法,都是比面向过程更加方便的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java大文件上传、分片上传、多文件上传、断点续传、上传文件minio、分片上传minio等解决方案

一、上传说明 文件上传花样百出&#xff0c;根据不同场景使用不同方案进行实现尤为必要。通常开发过程中&#xff0c;文件较小&#xff0c;直接将文件转化为字节流上传到服务器&#xff0c;但是文件较大时&#xff0c;用普通的方法上传&#xff0c;显然效果不是很好&#xff0c…

nginx的配置粗记

小白nginx的配置随笔&#xff08;随便记记&#xff09; 前言 我们都知道nginx有很多用途&#xff0c;比如&#xff1a;负载均衡&#xff0c;反向代理&#xff0c;网关路由&#xff0c;解决跨域等问题。我这次开发项目&#xff0c;用到的一些功能也涉及到了对nginx的配置&#…

Spark介绍及RDD操作

Spark介绍及RDD操作 PySpark简介spark特点运行原理spark实例化 SparkCore-RDDRDD创建转换&#xff08;Transformation&#xff09;行动&#xff08;Action&#xff09; PySpark简介 spark特点 运行速度快&#xff1a;DAG内存运算容易使用&#xff1a;Java、Scala、Python、R通…

Kubernetes——YAML文件编写

目录 一、创建Kubernetes对象YAML文件必备字段 1.apiVersion 2.kind 3.metadata 4.spec 二、YAML格式基本规范 1.结构表示 2.键值对 3.列表&#xff08;数组&#xff09; 4.字典&#xff08;映射&#xff09; 5.数据类型 6.注释 7.多文档支持 8.复杂结构 9.示例 …

快速排序与归并排序(非递归)

目录 快速排序&#xff08;双指针法&#xff09; 原理 代码 快速排序&#xff08;非递归&#xff09; 原理 代码 归并排序 介绍 优点 缺点 图片 原理 代码 归并排序&#xff08;非递归&#xff09; 代码 快速排序&#xff08;双指针法&#xff09; 快速排序的精…

【讲解下常见的分类算法,什么是分类算法?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

redis如何实现分布式锁

Redisson是怎么实现分布式锁的 分布式锁&#xff1a;Redisson 提供了一种简单而强大的方式来实现分布式锁。 它支持多种锁模式&#xff0c;如公平锁、可重入锁、读写锁等&#xff0c;并且提供了锁的超时设置和自动释放功能。 锁的获取 在Redisson中常见获取锁的方式有 lock() …

面向对象概述

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 面向对象&#xff08;Object Oriented&#xff09;的英文缩写是OO&#xff0c;它是一种设计思想。从20世纪60年代提出面向对象的概念到现在&#xff…

Cyber Weekly #9

赛博新闻 1、OpenAI&#xff1a;GPTs向全部用户开放&#xff0c;使用GPT-4o OpenAI宣布所有ChatGPT免费用户现在可以在GPT商店中使用GPTs&#xff0c;并且这些GPTs现在使用最新的GPT-4o模型。 2、马斯克 vs. Yann LeCun 这一周&#xff0c;AI圈最热闹的莫过于马斯克和LeCun的…

scGPT实验解读

本篇内容为发表在Nature Methods上的scGPT的部分实验内容 来自&#xff1a;scGPT: toward building a foundation model for single-cell multi-omics using generative AI, Nature Methods, 2024 目录 scGPT揭示特定细胞状态的基因网络缩放法则和迁移学习中的上下文效应 scGP…

基于安卓的虫害识别软件设计--(2)模型性能可视化|混淆矩阵、热力图

1.混淆矩阵&#xff08;Confusion Matrix&#xff09; 1.1基础理论 &#xff08;1&#xff09;在机器学习、深度学习领域中&#xff0c;混淆矩阵常用于监督学习&#xff0c;匹配矩阵常用于无监督学习。主要用来比较分类结果和实际预测值。 &#xff08;2&#xff09;图中表达…

物理模拟技术在AI绘画中的革新作用

引言&#xff1a; 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;艺术领域也迎来了一场创新的革命。AI绘画&#xff0c;作为这场革命的重要组成部分&#xff0c;不仅改变了传统艺术创作的模式&#xff0c;而且为艺术家提供了前所未有的创作工具。在这一过程…

Linux基础1-基本指令1

1.Linux学习前言 Linux的学习非常重要&#xff0c;我们学习Linux的第一步是在电脑中搭建Linux环境。 对于没有搭建过的可以看这阿伟t的一篇文章 【Linux入门】Linux环境配置-CSDN博客 我的环境为XShell,运行的云服务器是阿里云 2.本章重点 1.显示当前目录下的所有文件…

软件杯 题目:基于卷积神经网络的手写字符识别 - 深度学习

文章目录 0 前言1 简介2 LeNet-5 模型的介绍2.1 结构解析2.2 C1层2.3 S2层S2层和C3层连接 2.4 F6与C5层 3 写数字识别算法模型的构建3.1 输入层设计3.2 激活函数的选取3.3 卷积层设计3.4 降采样层3.5 输出层设计 4 网络模型的总体结构5 部分实现代码6 在线手写识别7 最后 0 前言…

展现市场布局雄心,ATFX再度亮相非洲峰会,开启区域市场新篇章

自2023年全球市场营销战略部署实施以来&#xff0c;ATFX在全球各区域市场取得了丰硕成果&#xff0c;其品牌实力、知名度、影响力均有大幅提升。在这场全球扩张的征程中&#xff0c;非洲市场日益成为集团关注的焦点。自2023年首次踏上这片充满潜力的市场以来&#xff0c;ATFX持…

定义类并创建类的实例

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中&#xff0c;类表示具有相同属性和方法的对象的集合。在使用类时&#xff0c;需要先定义类&#xff0c;然后再创建类的实例&#xff0c;通…

谨以此文章记录我的蓝桥杯备赛过程

以国优秀结束了蓝桥杯cb组 鄙人来自电信学院&#xff0c;非科班出身&#xff0c;在寒假&#xff0c;大约2024年2月份&#xff0c;跟着黑马程序员将c基础语法学完了&#xff0c;因为过年&#xff0c;事情较多&#xff0c;没在学了。 最初就是抱着拿省三的态度去打这个比赛的&a…

低代码是什么?开发系统更有什么优势?

低代码&#xff08;Low-Code&#xff09;是一种应用开发方法&#xff0c;它采用图形化界面和预构建的模块&#xff0c;使得开发者能够通过少量的手动编程来快速创建应用程序。这种方法显著减少了传统软件开发中的手动编码量&#xff0c;提高了开发效率&#xff0c;降低了技术门…

图形学初识--多边形剪裁算法

文章目录 前言正文为什么需要多边形剪裁算法&#xff1f;前置知识二维直线直线方程&#xff1a;距离本质&#xff1a;点和直线距离关系&#xff1a; 三维平面平面方程距离本质&#xff1a;点和直线距离关系&#xff1a; Suntherland hodgman算法基本介绍基本思想二维举例问题描…

mysql中EXPLAIN详解

大家好。众所周知&#xff0c;MySQL 查询优化器的各种基于成本和规则的优化会后生成一个所谓的执行计划&#xff0c;这个执行计划展示了接下来具体执行查询的方式。在日常工作过程中&#xff0c;我们可以使用EXPLAIN语句来查看某个查询语句的具体执行计划&#xff0c; 今天我们…