这个程序包含了 ATM 的核心功能:

- 账户验证
- 余额查询
- 取款
- 存款
- 转账
- 交易历史记录
- 退出系统
程序结构
为了代码的清晰和可维护性,我们将其分为几个类:
Account.java: 定义银行账户的属性(账号、密码、余额、交易历史)。ATM.java: ATM 的核心逻辑,处理用户的各种操作。ATMSystem.java: 程序的入口点,负责启动 ATM 系统和主菜单。Transaction.java: 一个简单的枚举,用于定义交易类型。
Transaction.java (交易类型枚举)
这个类用于标准化交易记录的类型。
// Transaction.java
public enum Transaction {
DEPOSIT("存款"),
WITHDRAW("取款"),
TRANSFER("转账");
private final String description;
Transaction(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
Account.java (账户类)
这个类表示一个银行账户,包含了账户的基本信息和操作方法。
// Account.java
import java.util.ArrayList;
import java.util.List;
public class Account {
private String accountNumber;
private String pin;
private double balance;
private List<String> transactionHistory;
public Account(String accountNumber, String pin, double initialBalance) {
this.accountNumber = accountNumber;
this.pin = pin;
this.balance = initialBalance;
this.transactionHistory = new ArrayList<>();
// 记录初始开户信息
addTransaction("账户创建", initialBalance);
}
public boolean validatePin(String enteredPin) {
return this.pin.equals(enteredPin);
}
public double getBalance() {
return balance;
}
public String getAccountNumber() {
return accountNumber;
}
public void deposit(double amount) {
if (amount > 0) {
this.balance += amount;
addTransaction(Transaction.DEPOSIT.getDescription(), amount);
} else {
System.out.println("存款金额必须大于0。");
}
}
public boolean withdraw(double amount) {
if (amount <= 0) {
System.out.println("取款金额必须大于0。");
return false;
}
if (amount > this.balance) {
System.out.println("余额不足。");
return false;
}
this.balance -= amount;
addTransaction(Transaction.WITHDRAW.getDescription(), -amount);
return true;
}
public boolean transfer(Account toAccount, double amount) {
if (amount <= 0) {
System.out.println("转账金额必须大于0。");
return false;
}
if (amount > this.balance) {
System.out.println("余额不足,无法转账。");
return false;
}
// 执行转账
this.balance -= amount;
toAccount.balance += amount;
// 记录交易历史
this.addTransaction(Transaction.TRANSFER.getDescription() + "至 " + toAccount.getAccountNumber(), -amount);
toAccount.addTransaction(Transaction.TRANSFER.getDescription() + "来自 " + this.getAccountNumber(), amount);
return true;
}
private void addTransaction(String type, double amount) {
String record = String.format("[%s] %s: %.2f, 余额: %.2f",
java.time.LocalDateTime.now(),
type,
amount,
this.balance);
transactionHistory.add(record);
}
public void printTransactionHistory() {
System.out.println("----- 交易历史 -----");
if (transactionHistory.isEmpty()) {
System.out.println("暂无交易记录。");
} else {
for (String record : transactionHistory) {
System.out.println(record);
}
}
System.out.println("--------------------");
}
}
ATM.java (ATM 核心逻辑类)
这是 ATM 的大脑,负责处理与用户的交互和所有业务逻辑。

// ATM.java
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class ATM {
private Map<String, Account> accounts;
private Account currentAccount;
private Scanner scanner;
public ATM() {
this.accounts = new HashMap<>();
this.scanner = new Scanner(System.in);
// 初始化一些测试账户
initializeAccounts();
}
private void initializeAccounts() {
accounts.put("123456", new Account("123456", "1234", 5000.00));
accounts.put("654321", new Account("654321", "4321", 3000.00));
System.out.println("ATM系统已启动,预设账户已加载。");
}
public void start() {
System.out.println("欢迎使用 ATM 模拟系统");
while (true) {
if (currentAccount == null) {
// 未登录状态,显示主菜单
showMainMenu();
} else {
// 已登录状态,显示用户菜单
showUserMenu();
}
}
}
private void showMainMenu() {
System.out.println("\n===== ATM 主菜单 =====");
System.out.println("1. 插入银行卡");
System.out.println("2. 退出");
System.out.print("请选择操作: ");
int choice = getIntInput(1, 2);
switch (choice) {
case 1:
login();
break;
case 2:
System.out.println("感谢使用,再见!");
System.exit(0);
break;
}
}
private void showUserMenu() {
System.out.println("\n===== 用户菜单 =====");
System.out.println("欢迎, " + currentAccount.getAccountNumber());
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.print("请选择操作: ");
int choice = getIntInput(1, 6);
switch (choice) {
case 1:
checkBalance();
break;
case 2:
withdraw();
break;
case 3:
deposit();
break;
case 4:
transfer();
break;
case 5:
showTransactionHistory();
break;
case 6:
logout();
break;
}
}
private void login() {
System.out.print("请输入账号: ");
String accountNumber = scanner.nextLine();
System.out.print("请输入密码: ");
String pin = scanner.nextLine();
Account account = accounts.get(accountNumber);
if (account != null && account.validatePin(pin)) {
currentAccount = account;
System.out.println("登录成功!");
} else {
System.out.println("账号或密码错误,请重试。");
}
}
private void logout() {
System.out.println("您已成功退卡。");
currentAccount = null;
}
private void checkBalance() {
System.out.printf("当前余额为: %.2f\n", currentAccount.getBalance());
}
private void withdraw() {
System.out.print("请输入取款金额: ");
double amount = getDoubleInput();
if (currentAccount.withdraw(amount)) {
System.out.println("取款成功!请取走您的现金。");
}
// 如果失败,withdraw方法内部已打印错误信息
}
private void deposit() {
System.out.print("请输入存款金额: ");
double amount = getDoubleInput();
currentAccount.deposit(amount);
System.out.println("存款成功!");
}
private void transfer() {
System.out.print("请输入对方账号: ");
String toAccountNumber = scanner.nextLine();
Account toAccount = accounts.get(toAccountNumber);
if (toAccount == null) {
System.out.println("对方账号不存在。");
return;
}
if (toAccount.equals(currentAccount)) {
System.out.println("不能向自己转账。");
return;
}
System.out.print("请输入转账金额: ");
double amount = getDoubleInput();
if (currentAccount.transfer(toAccount, amount)) {
System.out.println("转账成功!");
}
// 如果失败,transfer方法内部已打印错误信息
}
private void showTransactionHistory() {
currentAccount.printTransactionHistory();
}
// --- 辅助方法:处理用户输入 ---
private int getIntInput(int min, int max) {
while (true) {
try {
int choice = Integer.parseInt(scanner.nextLine());
if (choice >= min && choice <= max) {
return choice;
} else {
System.out.printf("请输入 %d 到 %d 之间的数字,\n", min, max);
}
} catch (NumberFormatException e) {
System.out.println("无效输入,请输入一个数字。");
}
}
}
private double getDoubleInput() {
while (true) {
try {
return Double.parseDouble(scanner.nextLine());
} catch (NumberFormatException e) {
System.out.println("无效输入,请输入一个有效的数字。");
}
}
}
}
ATMSystem.java (程序入口)
这个类只有一个 main 方法,用于创建并启动 ATM。
// ATMSystem.java
public class ATMSystem {
public static void main(String[] args) {
ATM atm = new ATM();
atm.start();
}
}
如何运行
- 保存文件: 将以上四个类分别保存为
Transaction.java,Account.java,ATM.java, 和ATMSystem.java文件,并将它们放在同一个目录下。 - 编译: 打开命令行或终端,进入该目录,然后运行
javac *.java来编译所有 Java 文件。 - 运行: 编译成功后,运行
java ATMSystem来启动程序。
示例运行流程
欢迎使用 ATM 模拟系统
ATM系统已启动,预设账户已加载。
===== ATM 主菜单 =====
1. 插入银行卡
2. 退出
请选择操作: 1
请输入账号: 123456
请输入密码: 1234
登录成功!
===== 用户菜单 =====
欢迎, 123456
1. 查询余额
2. 取款
3. 存款
4. 转账
5. 查看交易历史
6. 退卡
请选择操作: 1
当前余额为: 5000.00
===== 用户菜单 =====
欢迎, 123456
1. 查询余额
2. 取款
3. 存款
4. 转账
5. 查看交易历史
6. 退卡
请选择操作: 2
请输入取款金额: 500
取款成功!请取走您的现金。
===== 用户菜单 =====
欢迎, 123456
1. 查询余额
2. 取款
3. 存款
4. 转账
5. 查看交易历史
6. 退卡
请选择操作: 5
----- 交易历史 -----
[2025-10-27T10:30:00.123] 账户创建: 5000.00, 余额: 5000.00
[2025-10-27T10:30:15.456] 取款: -500.00, 余额: 4500.00
--------------------
===== 用户菜单 =====
欢迎, 123456
1. 查询余额
2. 取款
3. 存款
4. 转账
5. 查看交易历史
6. 退卡
请选择操作: 6
您已成功退卡。
===== ATM 主菜单 =====
1. 插入银行卡
2. 退出
请选择操作: 2
感谢使用,再见!
程序特点与可扩展性
- 面向对象: 使用类和对象来组织代码,结构清晰。
- 职责分离:
Account负责账户数据,ATM负责流程控制,ATMSystem负责启动。 - 健壮性: 对用户输入进行了基本的错误处理(非数字输入、范围检查)。
- 可扩展性:
- 数据库集成: 目前的账户数据存储在
HashMap中,可以轻松替换为数据库(如 MySQL, SQLite)来持久化数据。 - 更多功能: 可以轻松添加新功能,例如修改密码、支付账单等,只需在
showUserMenu中添加选项并实现相应方法。 - GUI界面: 可以将这个纯文本版本的后端逻辑保留,然后开发一个图形用户界面来替换
ATM类中的控制台交互部分。
- 数据库集成: 目前的账户数据存储在
