扩展 Account1 类为 Account2 类: (Account1类为版本1内的)
■ Account2 类继承 Account1 类。
■ 为 Account2 类新增一个名为 password 的 String 类型的私有数据域存储账号密码。
password 只能为字母或数字,长度不能小于 6 且不能大于 10。
■ 为 Account2 类新增一个名为 name 的 String 类型的私有数据域存储客户名字。
■ 为 Account2 类新增一个名为 transactions 的 ArrayList 类型的新数据域,其为客户存储交易记录。这要求新建一个名为 Transaction 的类,类的定义请参照教材第 10 版 P381。每笔交易都是 Transaction 类的一个实例。
■ 新增一个带初始余额的构造方法,其 id 随机产生,但不能与当前系统的 id 重复。若初始余额的参数为负数,则抛出一个自定义异常并在当前构造方法中进行处理。
■ 重写方法 withDraw,要求支取的金额为 100 的整数倍,并且当日支取金额不能超过5000,支取金额不允许透支。每进行一次操作应向 transactions 数组线性表添加一笔交易。
■ 重写方法 deposit,要求每进行一次操作应向 transactions 数组线性表添加一笔交易。
■ 新增一个方法 changePassword,只有旧密码正确,新密码符合要求,且两次输入相同的情况下才可以成功修改密码
设计测试类 ATMMachine2,其主菜单如下:
Main menu
0:create a account
1: check balance
2: withdraw
3: deposit
4:details of the transaction
5: change password
6:exit
■ 若 用 户 选 择 新 建 一 个 账 号 , 则 应 提 示 用 户 输 入 账 号 password 、 balance 和 annualInterestRate,其中 id 随机产生。新产生的账户应序列化到名为 accounts.dat 的文件中。
所有账户只能通过这种方式产生。
■ 所有用户操作结果应同步到 accounts.dat 文件中相应账户中。
■ 所有用户操作应有友好、简介的提示语。
1.创建一个名为Account2的类,该类继承Account1类,实现了可序列化接口,继承了Account1的相关方法和属性,由于不满足Account2类的需求,所以根据题目要求,创建了一个名为name的String类型的私有数据域;一个名为password的String类型的私有数据域;创建一个类型为Transaction的列表,Transaction类下面进行阐述;设置了一个isCorrectPassword()方法,用于判断用户输入的密码是否是6到10位的,而且只能为字母和数字,如果是,则返回true,否则返回false;
类Account2提供了password和name的访问器和修改器,子类新增了带特定id和balance的构造方法,其中id为随机数,我使用了Math.Random()产生,balance不能负数,否则会抛出一个自定义的异常;子类Account2重写了父类的withDraw()和deposit()方法,当取款金额不是100的整数或取款金额大于余额的时候,会进行提示,用户没进行一次存款和取款的操作,都需要向transactions添加一笔交易;类中包含一个changePassword()方法,我这里使用了多层判断,当用户需要修改密码的是时候,用户输入原密码,如果原密码正确,则输入新的密码,密码合法,则再次输入,输入的密码和第一次输入的密码相同,则修改密码成功,否则修改失败。
2.创建一个Transaction类,创建一个名为dateCreated的Date类型的私有数据域,一个名为type的char类型的私有数据域,一个名为amount、balance的double类型的私有数据域,一个名为description的String类型的私有数据域;在里面包含所有私有数据域的访问器和修改器,还在里面创建了一个无参构造方法,一个带特定类型、金额、余额、描述的有参构造方法,如果是取款,则balance是balance减去amount,如果是存款,则balance是balance加上amount。
3.测试类ATMMachine2:
用户登录,显示菜单,用户可输入0、1、2、3、4、5、6分别执行创建账户、查询余额、取款、存款、查询记录、修改密码、退出等操作。
(1)当用户输入0的时候会随机产生一个id,执行openAccount()方法,openAccount()方法里设置了一个名为same的变量,初始值为0,for循环用于判断随机生成的id是否已经存在,如果存在,则same等于1,输出用户id已被使用,否则same等于0,用户输入密码、余额、名字,然后创建Account2对象,并将创建的对象添加到accounts列表中。
当用户输入不为0时,不会更改id。
(2)当用户输入1的时候,获取accounts列表中相应的Account2对象,并通过getBalance()方法返回用户的余额。
(3)当用户输入为2的时候,提示用户输入取款金额,获取accounts列表中相应的Account2对象,并通过withDraw()方法取出金额。
(4)当用户输入为3的时候,提示用户输入存款金额,获取accounts列表中相应的Account2对象,并通过deposit()方法存入金额。
(5)当用户输入为4的时候,通过获取accounts列表中相应的Account2对象,并调用其中的transactions列表,再调用其中的方法访问用户进行的一些列操作,然后输出。
(6)当用户输入为5时,获取accounts列表中相应的Account2对象,并通过changePassword()修改密码。
(7)当用户输入为6时,将isLogin设置为false。
否则要求用户输入一个正确的命令。
每次创建一个对象的时候,使用writeObject将对象列表写入到一个名为accounts.dat的文件中,同时将对该账户的一系列操作都存放发文件中。
相关函数:
displayMenu():展示菜单
processMenu():执行1.创建账户、2.取款、3.存款、4.查询记录、5.修改密码、6.退出相关的操作
getBalance():查询余额
withDraw():取款
deposit():存款
changePassword():修改密码
getCorrectIdIndex():由于是随机产生id的,而存储的时候是顺序存储的,该函数是获取正确的id的下标的。
OpenAccount():创建一个账户,将账户的信息存放在列表中。
相关类中有一些set和get方法,用于修改和获取一些数据域信息。
输入数据 | 创建账户:输入密码、余额、名字,取款200,存款400,查询记录,更改密码 |
---|---|
预期输出 | 账户余额为1200,记录信息,密码修改成功 |
实际输出 |
Account2类
package version2;
import version1.Account1;
import version1.InvalidBalanceException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @Auther: paradise
* @Date: 2021/6/24 - 06 - 24 - 15:48
*/
public class Account2 extends Account1 implements Serializable {
private String password;
private String name;
ArrayList<Transaction> transactions = new ArrayList<>();
/**Constructing a parameter-less construction method*/
public Account2(){
}
/**Constructing a construction method with special id and balance*/
public Account2(int id,double balance) throws InvalidBalanceException {
super(id, balance);
}
/**Return the password*/
public String getPassword() {
return password;
}
/**Judge whether the password is qualified**/
public boolean isCorrectPassword(String string) {
if (6 <= string.length() && 10 >= string.length()) {
for (int i = 0; i < string.length(); i++) {
if (!Character.isLetterOrDigit(string.charAt(i))) {
return false;
}
}
return true;
}
else {
return false;
}
}
/***Set the Password*/
public void setPassword(String password) {
if(isCorrectPassword(password)){
this.password = password;
}
else{
System.out.println("输入的密码为6至10位且只能为字母或数字");
}
}
/***Return thr name*/
public String getName() {
return name;
}
/**Set the Name**/
public void setName(String name) {
this.name = name;
}
@Override
public void withDraw(double withdrawalAmount) throws InvalidBalanceException {
if(withdrawalAmount % 100 == 0 && 0 < withdrawalAmount && withdrawalAmount <= 5000){
transactions.add(new Transaction('W', withdrawalAmount, getBalance(), name));
setBalance(getBalance() - withdrawalAmount);
}
else{
System.out.println("支取金额需要为100的整数倍,并且支出金额要大于0,不能超过5000");
}
}
@Override
public void deposit(double depositAmount) throws InvalidBalanceException {
transactions.add(new Transaction('D', depositAmount, getBalance(), name));
setBalance(getBalance() + depositAmount);
}
public void changePassword(){
Scanner input = new Scanner(System.in);
System.out.println("请输入原密码:");
String string = input.next();
if(password.equals(string)){
System.out.println("请输入新的密码:");
String newPassword1 = input.next();
if(!isCorrectPassword(newPassword1)){
System.out.println("输入的密码不合法");
}
else{
System.out.println("请再一次输入您的密码:");
String newPassword2 = input.next();
if(newPassword1.equals(newPassword2)){
setPassword(newPassword1);
}
else{
System.out.println("两次输入的密码不一致");
}
}
}
else{
System.out.print("密码输入错误!!!");
}
}
}
Transaction类
package version2;
import java.util.Date;
/**
* @Auther: paradise
* @Date: 2021/6/24 - 06 - 24 - 15:49
*/
public class Transaction{
private Date dateCreated;
private char type;
private double amount;
private double balance;
private String description;
/**Create a null parameter construction method*/
public Transaction(){
}
/**Create a construction method with special type, amount, balance, description*/
public Transaction(char type, double amount, double balance, String description) {
if(type == 'W'){
this.type = type;
this.amount = amount;
this.balance = balance - amount;
this.description = description;
}
if(type == 'D'){
this.type = type;
this.amount = amount;
this.balance = balance + amount;
this.description = description;
}
}
/**Set the date created*/
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
/**Return the type*/
public char getType() {
return type;
}
/**Set the type*/
public void setType(char type) {
this.type = type;
}
/**Return the amount*/
public double getAmount() {
return amount;
}
/**Set the amount*/
public void setAmount(double amount) {
this.amount = amount;
}
/**Get the balance*/
public double getBalance() {
return balance;
}
/**Set the balance*/
public void setBalance(double balance) {
this.balance = balance;
}
/**Return the description*/
public String getDescription() {
return description;
}
/**Set thr description*/
public void setDescription(String description) {
this.description = description;
}
/**Return the date*/
public Date getDateCreated() {
dateCreated = new Date();
return dateCreated;
}
}
ATMMachine2类
package version2;
import version1.InvalidBalanceException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @Auther: paradise
* @Date: 2021/6/24 - 06 - 24 - 15:49
*/
public class ATMMachine2{
private static Scanner scanner;
private static boolean isLogin = true;
private static ArrayList<Account2> accounts = new ArrayList<Account2>(100);
static int id = (int)(Math.random() * 100);
/**Display the menu*/
public static void displayMenu(){
System.out.print("Main menu" + "\n0: create a account" + "1: check balance\n" +
"2: withdraw\n" + "3: deposit\n" + "4: details of the transaction\n" + "5: change password\n" + "6: exit\n");
System.out.print("Enter a choice: ");
}
public static int getCorrectIdIndex(int id){
int index = -1;
for(int i = 0; i < accounts.size(); i++){
if(accounts.get(i).getId() == id){
index = i;
}
}
return index;
}
/**Display the process menu*/
public static void processMenu(int id, int command) throws InvalidBalanceException,IndexOutOfBoundsException {
try{
switch (command) {
case 0:
openAccount(id);
case 1:
System.out.print("The balance is " + accounts.get(getCorrectIdIndex(id)).getBalance() + "\n" );
break;
case 2:
System.out.print("Enter an amount to withdraw: " );
double withdrawMoney = scanner.nextDouble();
accounts.get(getCorrectIdIndex(id)).withDraw(withdrawMoney);
break;
case 3:
System.out.print("Enter an amount to deposit:" );
double depositMoney = scanner.nextDouble();
accounts.get(getCorrectIdIndex(id)).deposit(depositMoney);
break;
case 4:
System.out.print(" The name of the account \t The type \t The dispatch amount\t The balance\n");
for(int i = 0; i < accounts.get(getCorrectIdIndex(id)).transactions.size(); i++){
System.out.println(
(i+1) + " " + accounts.get(getCorrectIdIndex(id)).getName() + " "
+ accounts.get(getCorrectIdIndex(id)).transactions.get(i).getType() + " "+
accounts.get(getCorrectIdIndex(id)).transactions.get(i).getAmount() + " " +
accounts.get(getCorrectIdIndex(id)).transactions.get(i).getBalance());
}
break;
case 5:
accounts.get(getCorrectIdIndex(id)).changePassword();
case 6:
isLogin = false;
break;
default:
System.out.println("please enter a right command:");
break;
}}
catch (IndexOutOfBoundsException e){
System.out.println("需要先创建一个用户");
}
}
public static void openAccount(int id) throws InvalidBalanceException {
int same = 0;
for (int i = 0; i < accounts.size(); i++) {
if(id == accounts.get(i).getId()){
same = 1;
break;
}
}
if(same == 1){
System.out.print("This id has been used");
}
else{
System.out.println("Please enter your password:");
String password = scanner.next();
System.out.println("Please enter your balance:");
Double balance = scanner.nextDouble();
System.out.println("Please enter your name:");
String name = scanner.next();
Account2 account2 = new Account2(id, balance);
account2.setPassword(password);
account2.setAnnualInterestRate(0.015);
account2.setName(name);
accounts.add(account2);
}
}
//这是一个main方法,是程序的入口
public static void main(String[] args) throws InvalidBalanceException, IOException, ClassNotFoundException{
while (true) {
isLogin = true;
while (isLogin) {
displayMenu();
scanner = new Scanner(System.in);
int command = scanner.nextInt();
if(command == 0){
id = (int)(Math.random() * 100);
processMenu(id, command);
try(ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("accounts.dat"))) {
output.writeObject(accounts);
for (int i = 0; i < accounts.size(); i++) {
List<Transaction> transactionsList = accounts.get(i).transactions;
output.writeObject(transactionsList);
}
}
}
else{
processMenu(id, command);
}
}
}
}
}
版本三将通过JavaFX构建图形化界面,尽情期待哦~