ATM系统

279 阅读8分钟

技术选型

  1. 面向对象编程: 每个用户账户都是一个对象:所以需要设计账户类Account用于创建账户对象封装账户信息。
  2. 程序流程控制:需要结合分支、循环、跳转关键字等相关操作控制程序的业务逻辑。
  3. 使用集合容器:系统需要提供一个容器用于存储这些账户对象的信息,我们选ArrayList集合。
  4. 使用常见API:登录信息的内容比较,业务数据的分析,处理等都需要用到String等常用API来解决。

将会收获的能力

  1. 优秀的面向对象编程能力。
  2. 清晰、缜密的业务、数据分析能力。
  3. 熟练使用程序流程技术来控制计算机完成自己的想法。
  4. 形成良好的编码习惯,获得一定的编码经验。提升业务分析和解决问题的能力,让基础知识形成体系结构,为后续Java高级技术的学习做有力的支撑。

项目设计及各功能实现步骤

1.账户类、首页设计

分析:

  1. 每个用户的账户信息都是一个对象,需要提供账户类。
  2. 需要准备一个容器,用于存储系统全部账户对象信息。
  3. 首页只需要包含:登录和注册2个功能。

实现步骤:

  1. 定义账户类,用于后期创建账户对象封装用户的账户信息。
  2. 账户类中的信息至少需要包含(卡号、姓名、密码、余额、取现额度)
  3. 需要准备一个ArrayList的集合,用于存储系统用户的账户对象。
  4. 需要展示欢迎页包含2个功能:开户功能、登录账户。

2.开户功能

分析: 开户功能其实就是就是往系统的集合容器中存入一个新的账户对象的信息。

实现步骤:

  1. 开户应该定义成一个方法,并传入账户集合
  2. 创建一个Account账户类的对象用于封装账户信息(姓名、密码、卡号)
  3. 键盘录入姓名、密码、确认密码(需保证两次密码一致)
  4. 生成账户卡号,卡号必须由系统自动生成8位数字(必须保证卡号的唯一)
  5. 把Account账户对象存入到集合accounts中去。

3.登录功能

分析:

  1. 登录功能应该定义成一个方法,并传入账户集合:
  2. 让用户输入卡号,根据卡号去账户集合中查询账户对象。
  3. 如果没有找到账户对象,说明登录卡号不存在,提示继续输入卡号。
  4. 如果找到了账户对象,说明卡号存在,继续输入密码。
  5. 如果密码不正确,提示继续输入密码
  6. 如果密码也正确,登陆成功!

实现步骤:

  1. 根据卡号去账户集合中查询对应的账户对象。
  2. 如果找到了账户对象,说明卡号存在,继续输入密码。
  3. 如果密码也正确,则登录成功。

4.操作页设计、查询账户、退出账户功能功能

分析:

  1. 用户登录成功后,需要进入用户操作页。
  2. 查询就是直接展示当前登录成功的账户对象的信息。
  3. 退出账户是需要回到首页的。

5.存款功能

分析:

  1. 存款就是拿到当前账户对象。
  2. 然后让用户输入存款的金额。
  3. 调用账户对象的setMoney方法将账户余额修改成存钱后的余额。
  4. 存钱后需要查询一下账户信息,确认是否存钱成功了!

6.取款功能

分析:

  1. 取款需要先判断账户是否有钱。
  2. 有钱则拿到自己账户对象。
  3. 然后让用户输入取款金额
  4. 判断取款金额是否超过了当次限额,以及余额是否足够
  5. 满足要求则调用账户对象的setMoney方法完成金额的修改。

7.转账功能

分析:

  1. 转账功能需要判断系统中是否有2个账户对象及以上。
  2. 同时还要判断自己账户是否有钱。
  3. 接下来需要输入对方卡号,判断对方账户是否存在。
  4. 对方账户存在还需要认证对方户主的姓氏。
  5. 满足要求则可以把自己账户对象的金额修改到对方账户对象中去。

8.密码修改、销户功能

分析:

  1. 修改密码就是把当前对象的密码属性使用set方法进行更新。
  2. 销户是从集合对象中删除当前对象,并回到首页。

完整代码

Account类

package com.example;

public class Account {
    private String cardId;
    private String userName;
    private String password;
    // 账户余额
    private double money;
    // 取现额度
    private double quotaMoney;

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public double getQuotaMoney() {
        return quotaMoney;
    }

    public void setQuotaMoney(double quotaMoney) {
        this.quotaMoney = quotaMoney;
    }
}

ATMSystem类

package com.example;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

/**
 * ATM系统的入口类
 */
public class ATMSystem {
    public static void main(String[] args) {
        // 1.定义账户类
        // 2、定义一个集合容器,负责以后存储全部的账户对象,进行相关的业务操作
        ArrayList<Account> accounts = new ArrayList<>();
        // 3、展示系统的首页
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("==========黑马ATM系统==========");
            System.out.println("1、账户登录");
            System.out.println("2、账户开户");

            System.out.println("请您选择操作:");
            int command = scanner.nextInt();

            switch (command) {
                case 1:
                    // 用户登录操作
                    login(accounts, scanner);
                    break;
                case 2:
                    // 用户开户操作
                    register(accounts, scanner);
                    break;
                default:
                    System.out.println("您输入的操作命令不存在!");
            }
        }
    }

    /**
     * 登录功能
     *
     * @param accounts
     * @param scanner
     */
    private static void login(ArrayList<Account> accounts, Scanner scanner) {
        System.out.println("==========系统登录操作==========");
        // 判断账户集合中是否存在账户
        if (accounts.size() == 0) {
            System.out.println("对不起,当前系统中无任何账户,请先开户再进行登录!");
            return;
        }

        // 进入登录操作
        while (true) {
            System.out.println("请您输入卡号:");
            String cardId = scanner.next();
            Account account = getAccountByCardId(cardId, accounts);
            if (account != null) {
                // 认证密码
                while (true) {
                    System.out.println("请您输入登录密码:");
                    String password = scanner.next();
                    if (password.equals(account.getPassword())) {
                        // 登录成功
                        System.out.println("恭喜您," + account.getUserName() + "先生/女士,您已进入系统,您的卡号是:" + account.getCardId());
                        // 查询、转账、取款操作
                        showUserCommand(scanner, account, accounts);
                        return;
                    } else {
                        System.out.println("对不起,您输入的密码有误!");
                    }
                }
            } else {
                System.out.println("对不起,系统中不存在该账户的卡号!");
            }
        }
    }

    /**
     * 用户操作页面
     *
     * @param scanner
     * @param account
     * @param accounts
     */
    private static void showUserCommand(Scanner scanner, Account account, ArrayList<Account> accounts) {
        while (true) {
            System.out.println("==========用户操作页面==========");
            System.out.println("1、查询账户");
            System.out.println("2、存款");
            System.out.println("3、取款");
            System.out.println("4、转账");
            System.out.println("5、修改密码");
            System.out.println("6、退出");
            System.out.println("7、注销账户");
            System.out.println("请选择:");

            int command = scanner.nextInt();
            switch (command) {
                case 1:
                    // 查询当前账户信息
                    showAccount(account);
                    break;
                case 2:
                    // 存款
                    depositMoney(account, scanner);
                    break;
                case 3:
                    // 取款
                    drawMoney(account, scanner);
                    break;
                case 4:
                    // 转账
                    transferMoney(account, scanner, accounts);
                    break;
                case 5:
                    // 修改密码
                    updatePassword(account, scanner);
                    return;
                case 6:
                    // 退出
                    System.out.println("退出成功,欢迎下次光临!");
                    return;
                case 7:
                    deleteAccount(account, scanner, accounts);
                    break;
                default:
                    System.out.println("您输入的命令有误,请重新输入:");
            }
        }
    }

    /**
     * 注销账户
     *
     * @param account
     * @param scanner
     * @param accounts
     */
    private static void deleteAccount(Account account, Scanner scanner, ArrayList<Account> accounts) {
        System.out.println("您确定要注销该账户吗? y/n");
        String result = scanner.next();
        switch (result) {
            case "y":
                accounts.remove(account);
                System.out.println("您的账户销户完成!");
                return;
            case "n":
                System.out.println("已取消销户操作");
                break;
            default:
                System.out.println("您输入的命令不正确!");
        }
    }

    /**
     * 修改密码
     *
     * @param account
     * @param scanner
     */
    private static void updatePassword(Account account, Scanner scanner) {
        System.out.println("==========用户修改密码操作==========");
        while (true) {
            System.out.println("请您输入当前密码:");
            String password = scanner.next();
            if (password.equals(account.getPassword())) {
                while (true) {
                    System.out.println("请您输入新密码:");
                    String newPassword = scanner.next();

                    System.out.println("请您确认新密码");
                    String okNewPassword = scanner.next();
                    if (okNewPassword.equals(newPassword)) {
                        System.out.println("恭喜您密码修改成功!");
                        account.setPassword(newPassword);
                        return;
                    } else {
                        System.out.println("您2次输入的密码不一致!");
                    }
                }
            } else {
                System.out.println("您输入的密码不正确!");
            }
        }
    }

    /**
     * 转账功能
     *
     * @param account
     * @param scanner
     * @param accounts
     */
    private static void transferMoney(Account account, Scanner scanner, ArrayList<Account> accounts) {
        System.out.println("==========用户转账操作==========");
        // 账户集合中是否至少有两个账户
        if (accounts.size() < 2) {
            System.out.println("当前系统中不足2个账户,无法进行转账!");
            return;
        }
        // 判断自己账户是否有钱
        if (account.getMoney() == 0) {
            System.out.println("对不起,您自己都没钱,就别转了吧");
            return;
        }

        // 开始转账
        while (true) {
            System.out.println("请输入对方账户的卡号:");
            String cardId = scanner.next();
            // 不能时自己的卡号
            if (cardId.equals(account.getCardId())) {
                System.out.println("对不起,您不能向自己的账户进行转账操作!");
                continue;
            }
            Account account1 = getAccountByCardId(cardId, accounts);
            if (account1 == null) {
                System.out.println("对不起,您输入的卡号不存在!");
            } else {
                String userName = account1.getUserName();
                String tip = "*" + userName.substring(1);
                System.out.println("请您输入[" + tip + "]的姓氏:");
                String preName = scanner.next();
                if (userName.startsWith(preName)) {
                    while (true) {
                        System.out.println("请您输入转账金额:");
                        double money = scanner.nextDouble();
                        if (money > account.getMoney()) {
                            System.out.println("对不起,您当前账户余额不足,余额为:" + account.getMoney() + "元!");
                        } else {
                            account.setMoney(account.getMoney() - money);
                            account1.setMoney(account.getMoney() + money);
                            System.out.println("恭喜您转账成功!");
                            showAccount(account);
                            return;
                        }
                    }
                } else {
                    System.out.println("对不起,您输入的信息有误!");
                }

            }
        }
    }

    /**
     * 取款功能
     *
     * @param account
     * @param scanner
     */
    private static void drawMoney(Account account, Scanner scanner) {
        System.out.println("==========用户取款操作==========");
        if (account.getMoney() < 100) {
            System.out.println("对不起,当前账户余额不足100元,无法取款!");
            return;
        }

        while (true) {
            System.out.println("请您输入取款金额:");
            double money = scanner.nextDouble();
            if (money > account.getQuotaMoney()) {
                System.out.println("对不起,您当前取款金额超过每次取款限额,每次最多可取:" + account.getQuotaMoney() + "元!");
            } else if (money > account.getMoney()) {
                System.out.println("对不起,您当前账户余额不足,余额为:" + account.getMoney() + "元!");
            } else {
                account.setMoney(account.getMoney() - money);
                System.out.println("恭喜您取款成功!");
                showAccount(account);
                return;
            }
        }
    }

    /**
     * 存款功能
     *
     * @param account
     * @param scanner
     */
    private static void depositMoney(Account account, Scanner scanner) {
        System.out.println("==========用户存款操作==========");
        System.out.println("请你输入存款金额:");
        double money = scanner.nextDouble();
        account.setMoney(account.getMoney() + money);
        System.out.println("恭喜您,存款成功!");
        showAccount(account);
    }

    /**
     * 展示当前账户信息
     *
     * @param account
     */
    private static void showAccount(Account account) {
        System.out.println("==========当前账户信息如下==========");
        System.out.println("卡号:" + account.getCardId());
        System.out.println("户主:" + account.getUserName());
        System.out.println("余额:" + account.getMoney());
        System.out.println("取现额度:" + account.getQuotaMoney());
    }

    /**
     * 用户开户功能
     *
     * @param accounts 账户集合
     * @param scanner  控制台读入操作
     */
    private static void register(ArrayList<Account> accounts, Scanner scanner) {
        System.out.println("==========系统开户操作==========");
        // 1、创建一个账户对象,用于后期封装账户信息。
        Account account = new Account();
        // 2、录入当前这个账户的信息,注入到账户对象中去
        System.out.println("请您输入账户用户名:");
        String userName = scanner.next();
        account.setUserName(userName);

        while (true) {
            System.out.println("请您输入账户密码:");
            String password = scanner.next();
            System.out.println("请您输入确认密码:");
            String okPassword = scanner.next();
            if (okPassword.equals(password)) {
                account.setPassword(okPassword);
                break;
            } else {
                System.out.println("对不起,您输入的2次密码不一致,请重新确认!");
            }
        }

        System.out.println("请您输入账户每次取现额度:");
        double quotaMoney = scanner.nextDouble();
        account.setQuotaMoney(quotaMoney);

        // 为账户随机一个8位且与其他账户的卡号不重复的号码
        String cardId = getRandomCardId(accounts);
        account.setCardId(cardId);
        // 3、把账户对象添加到账户集合中去
        accounts.add(account);
        System.out.println("恭喜您," + userName + "先生/女士,您已开户成功,您的卡号是:" + cardId + ",请您妥善保管卡号。");
    }

    /**
     * 生成8位卡号
     *
     * @param accounts
     * @return
     */
    private static String getRandomCardId(ArrayList<Account> accounts) {
        // 生成8位数字
        String cardId = "";
        Random random = new Random();
        for (int i = 0; i < 8; i++) {
            cardId += random.nextInt(10);
        }

        // 判断是否重复
        Account account = getAccountByCardId(cardId, accounts);
        if (account == null) {
            return cardId;
        }
        return null;
    }

    /**
     * 根据卡号查询出一个账户对象出来
     *
     * @param cardId   卡号
     * @param accounts 全部账户的集合
     * @return 账户对象 / null
     */
    private static Account getAccountByCardId(String cardId, ArrayList<Account> accounts) {
        for (int i = 0; i < accounts.size(); i++) {
            Account account = accounts.get(i);
            if (account.getCardId().equals(cardId)) {
                return account;
            }
        }
        return null;
    }
}

注意:该项目为作者学习黑马程序员javase课程时做的练习项目