公众号:全干开发 。 专注分享简洁但高质量的动图技术文章!
项目概述
本教程适合刚学习完java基础语法的同学,涉及if语句、循环语句、类的封装、集合等基础概念,使用大量gif图帮助读者演示代码操作、效果等,是一个非常不错的巩固练习教程!不涉及任何java框架等内容,可以放心食用!
本教程将使用控制台模拟一个ATM取款机!
基础需求演示
ATM机主要有用户开户、用户登录(登录后可以转账等)功能,我们简单演示一下用户开户功能!
系统架构
根据我们的需求,我们可以知道,我们的这个程序应该主要包含两个类
- 账户类Account:包含卡号、姓名、性别、密码、余额、额度等属性
- ATM类:代表ATM系统,负责提供业务需求,具备欢迎页、转账、开通账户等功能
项目搭建
创建项目
打开编译器,创建名为Project_ATM的项目
创建Account类
Account类用来表示账户信息,包含卡号、姓名、性别、密码、余额、额度等属性,我们创建这个类,并完善一些基本属性
Acount的基本属性创建完毕后,我们需要给这些属性创建get和set方法,用来方便快捷的更改和读取这些数值。
我们使用IDEA的快捷操作:
光标放在Account类内部,右键点击【Generate】,点击【Getter and Setter】,点住ctrl键不放,选中Acoount的所有属性,点击【ok】即可
生成的代码如下:
public class Account {
private String cardId; // 卡号
private String userName; // 名称
private char sex; // 性别
private String passWord; // 密码
private double money; // 资产
private double limit; // 限额
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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
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 getLimit() {
return limit;
}
public void setLimit(double limit) {
this.limit = limit;
}
}
创建ATM类
ATM类用来模拟ATM系统的一些功能,最重要的,它应该能储存不同用户的账户信息(accounts),并且这个账户信息应该是私有的(private),不能随便被访问到。
我们创建这个类,并定义好所有用户的信息集合 accounts
import java.util.ArrayList;
public class ATM {
private ArrayList<Account> accounts = new ArrayList<>();
}
我们的欢迎页是在控制台显示的,长下面这个样子
我们用代码实现一下这个逻辑
import java.util.ArrayList;
import java.util.Scanner;
public class ATM {
private ArrayList<Account> accounts = new ArrayList<>();
// 创建一个新的Scanner对象,名为sc。Scanner对象用于获取用户键盘输入的值。
private Scanner sc = new Scanner(System.in);
public void start(){
System.out.println("===欢迎您进入到了ATM系统===");
System.out.println("1、用户登录");
System.out.println("2、用户开户");
System.out.println("请选择:");
// 调用nextInt()方法,等待用户输入一个整数,并将这个整数存储在变量command中。
int command = sc.nextInt();
switch (command) {
case 1:
//用户登录
break;
case 2:
//用户开户
break;
default:
System.out.println("操作错误!");
// 输入错误重新进入开始页
start();
}
}
}
现在,我们可以测试一下了。
创建Test类
想要验证我们的ATM功能是否ok,我们需要创建个Test类验证下:
public class Text {
public static void main(String[] args) {
// 创建atm类,代表一个ATM系统
ATM atm = new ATM();
//启动ATM系统
atm.start();
}
}
我们执行这个函数试试效果
不错,很完美!
开户功能完善
功能简介
开户功能就是新增一个账户,也就是向系统的账户集合添加一个账户对象, 这个账户对象应该包含用户输入的姓名、性别、密码及每次取现的额度信息;同时,还有一个系统生成的随机卡号(8位数字,不能重复)。
生成基础信息
我们在ATM类中创建一个开户操作createAccount方法
public class ATM {
private ArrayList<Account> accounts = new ArrayList<>();
// 创建一个新的Scanner对象,名为sc。Scanner对象用于获取用户键盘输入的值。
private Scanner sc = new Scanner(System.in);
public void start(){
// .....
}
// 用户开户操作
private void createAccount(){
}
}
这个createAccount方法应该做三件事儿:
- 创建一个账户对象,用于封装用户的开户信息
- 需要用户输入自己的开户信息,赋值给账户对象
- 把这个账户对象,存入到账户集合中去
第二步中,我们首先需要用户输入账户名称
private void createAccount(){
// 1、创建一个账户对象,用于封装用户的开户信息
Account account = new Account();
// 2、需要用户输入自己的开户信息,赋值给账户对象
System.out.println("请您输入您的账户名称:");
String name = sc.next() ;
account.setUserName(name);
// 3、把这个账户对象,存入到账户集合中去
}
sc.next()用于输出字符串
然后,需要用户输入性别
// 2、需要用户输入自己的开户信息,赋值给账户对象
// ....
System.out.println("请输入性别");
char sex = sc.next().charAt(0);
if (sex == '男' || sex == '女') {
account.setSex(sex);
} else {
System.out.println("输入无效,请输入男或女。");
}
// 3、把这个账户对象,存入到账户集合中去
注意:我们在Account类中定义性别用的是基本类型char,所以这里的sex用 char修饰。sc.next()返回的是字符串String类,所以我们用charAt(0)获取到这个字符串的第一个字符,将其转换成了char类型
上述代码中,如果用户没有按照我们的预期输入性别,我们应该让它重新输入,所以需要循环这部分代码。我们借助编译器添加while循环语句:选中代码,点击crtl+alt+T,选择while;if语句中,我们需要终止循环
最后,我们完善下其他方法
// 用户开户操作
private void createAccount(){
// 1、创建一个账户对象,用于封装用户的开户信息
Account account = new Account();
// 2、需要用户输入自己的开户信息,赋值给账户对象
System.out.println("请您输入您的账户名称:");
// sc.next()用于返回字符串
String name = sc.next() ;
account.setUserName(name);
while (true) {
System.out.println("请输入性别");
char sex = sc.next().charAt(0);
if (sex == '男' || sex == '女') {
account.setSex(sex);
break;
} else {
System.out.println("输入无效,请输入男或女。");
}
}
while (true){
System.out.println("请您输入您的账户密码:");
String passWord = sc.next();
System.out.println("请您输入您的确认密码:");
String okPassWord = sc.next();
// 判断2次密码是否一样。
if(okPassWord.equals(passWord)) {
account.setPassWord(okPassWord);
break;
} else {
System.out.println("您输入的2次密码不一致,请您确认~~");
}
}
System.out.println("请您输入您的取现额度:");
double limit = sc.nextDouble();
account.setLimit(limit);
// 3、把这个账户对象,存入到账户集合中去
注:卡号的生成比较复杂,我们先暂时忽略
现在,我们进行第三步,把生成的账户对象,存入到账户集合中。
// 3、把这个账户对象,存入到账户集合中去
accounts.add(account);
System.out.println("恭喜您,"+ account.getUserName() + "开户成功,您的卡号是:");
我们在Account类中完善一下getUserName方法
public String getUserName() {
return userName + ( sex == '男' ? "先生": "女士");
}
OK,现在我们在start方法中运行下createAccount()方法
然后再Tset类中运行程序试试看
丝滑流畅!
生长卡号信息
卡号是一个8位的数字,且和已有卡号不能重复,它的创建分为以下几个步骤
定义一个string类型的变量记住8位数字作为一个卡号
String cardId = "";
使用循环,循环8次,每次产生一个随机数给cardId连接起来
Random r = new Random();
for (int i = ; i < 8; i++) {
int data = r.nextInt( bound: 10); // 0 - 9
cardId += data;
}
判断cardId中记住的卡号,是否与其他账户的卡号重复了,没有重复,才可以做为一个新卡号返回.
Account acc = getAccountByCardId(cardId);
if(acc == null){
// 说明cardId没有找到账户对象,因此cardId没有与其他账户的卡号重复,可以返回它做为一个新卡号
return cardId;
}
详细代码如下
public void start(){ ... }
// 用户开户操作
private void createAccount(){ ... }
// 返回一个8位 数字的卡号,而且这个卡号不能与其他账户的卡号重复
private String createCardId(){
while (true) {
String cardId = "";
Random r = new Random();
for (int i = 0; i < 8; i++) {
int data = r.nextInt(10); // 0 - 9
cardId += data;
}
// 判断cardId中记住的卡号,是否与其他账户的卡号重复了,没有重复,才可以做为一个新卡号返回.
Account acc = getAccountByCardId(cardId);
if(acc == null){
// 说明cardId没有找到账户对象,因此cardId没有与其他账户的卡号重复,可以返回它做为一个新卡号
return cardId;
}
}
}
// 根据卡号查询账户对象返回 accounts = [c1,c2,c3。]
private Account getAccountByCardId(String cardId){
// 遍历全部的账户对象
for (int i = 0; i < accounts.size(); i++) {
Account acc = accounts.get(i);
// 判断这个账户对象acc 中的卡号是否是我们要找的卡号
if(acc.getCardId().equals(cardId)){
return acc;
}
}
return null; // 查无此账户,这个卡号不存在的
}
- get(int index):是集合特有的方法,用于返回指定位置的元素
- Random是一个类,它提供了生成各种类型的随机数的方法。
- nextInt(10)生成0-9之间的随机数
现在,我们就可以完善开户功能了!
// 用户开户操作
private void createAccount(){
// ...
String newCard = createCardId();
account.setCardId(newCard);
// 3、把这个账户对象,存入到账户集合中去
accounts.add(account);
System.out.println("恭喜您,"+ account.getUserName() + "开户成功,您的卡号是:" + newCard);
}
结语
至此,我们的开户功能就完成了!下面是开户功能的完整代码!
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class ATM {
private ArrayList<Account> accounts = new ArrayList<>();
// 创建一个新的Scanner对象,名为sc。Scanner对象用于获取用户键盘输入的值。
private Scanner sc = new Scanner(System.in);
public void start(){
System.out.println("===欢迎您进入到了ATM系统===");
System.out.println("1、用户登录");
System.out.println("2、用户开户");
System.out.println("请选择:");
// 调用nextInt()方法,等待用户输入一个整数,并将这个整数存储在变量command中。
int command = sc.nextInt();
switch (command) {
case 1:
//用户登录
break;
case 2:
//用户开户
createAccount();
break;
default:
System.out.println("操作错误!");
// 输入错误重新进入开始页
start();
}
}
// 用户开户操作
private void createAccount(){
// 1、创建一个账户对象,用于封装用户的开户信息
Account account = new Account();
// 2、需要用户输入自己的开户信息,赋值给账户对象
System.out.println("请您输入您的账户名称:");
// sc.next()用于返回字符串
String name = sc.next() ;
account.setUserName(name);
while (true) {
System.out.println("请输入性别");
char sex = sc.next().charAt(0);
if (sex == '男' || sex == '女') {
account.setSex(sex);
break;
} else {
System.out.println("输入无效,请输入男或女。");
}
}
while (true){
System.out.println("请您输入您的账户密码:");
String passWord = sc.next();
System.out.println("请您输入您的确认密码:");
String okPassWord = sc.next();
// 判断2次密码是否一样。
if(okPassWord.equals(passWord)) {
account.setPassWord(okPassWord);
break;
} else {
System.out.println("您输入的2次密码不一致,请您确认~~");
}
}
System.out.println("请您输入您的取现额度:");
double limit = sc.nextDouble();
account.setLimit(limit);
String newCard = createCardId();
account.setCardId(newCard);
// 3、把这个账户对象,存入到账户集合中去
accounts.add(account);
System.out.println("恭喜您,"+ account.getUserName() + "开户成功,您的卡号是:" + newCard);
}
// 返回一个8位 数字的卡号,而且这个卡号不能与其他账户的卡号重复
private String createCardId(){
while (true) {
String cardId = "";
Random r = new Random();
for (int i = 0; i < 8; i++) {
int data = r.nextInt(10); // 0 - 9
cardId += data;
}
// 判断cardId中记住的卡号,是否与其他账户的卡号重复了,没有重复,才可以做为一个新卡号返回.
Account acc = getAccountByCardId(cardId);
if(acc == null){
// 说明cardId没有找到账户对象,因此cardId没有与其他账户的卡号重复,可以返回它做为一个新卡号
return cardId;
}
}
}
// 根据卡号查询账户对象返回 accounts = [c1,c2,c3。]
private Account getAccountByCardId(String cardId){
// 遍历全部的账户对象
for (int i = 0; i < accounts.size(); i++) {
Account acc = accounts.get(i);
// 判断这个账户对象acc 中的卡号是否是我们要找的卡号
if(acc.getCardId().equals(cardId)){
return acc;
}
}
return null; // 查无此账户,这个卡号不存在的
}
}
接下来,我们会完成这个项目的另一个核心功能:用户登录及登录后的转账等等功能!