• 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类下面的方法中,后续我们只用调用它的方法就可以了。对于其它人想用我们的代码,或者说后续添加方法,都是比面向过程更加方便的。

  • 相关阅读:
    基于docker环境的tomcat开启远程调试
    如何使用数据选择器配置日期筛选框?
    【一周聚焦】 联邦学习 arxiv 2.16-3.10
    Spark 中的分桶分化
    变电站自动化系统中的安全措施分析及应用-安科瑞
    Leetcode-338. 比特位计数
    得物极光蓝纸箱尺寸设计实践
    Smile or Scowl? Looking at Infographic DesignThrough the Affective Lens
    【C语言】循环语句详解
    《HCIP-openEuler实验指导手册》1.3Apache动态功能模块加载卸载练习
  • 原文地址:https://blog.csdn.net/weixin_44064040/article/details/139391721