Java实现图书管理系统:OOP设计与完整源码解析
本教程通过Java手写一个简单的图书管理系统,详细讲解如何利用面向对象(OOP)特性进行系统设计。内容涵盖用户权限分类、书籍数据存储及核心功能的接口实现,帮助开发者掌握Java基础语法在实际工程中的综合应用。
在学习完Java基本语法后,通过一个小项目来串联知识点是非常有效的学习方式。我们将开发一个基于控制台的图书管理系统,核心目标是实现管理员与普通用户的不同权限操作,以及图书的增删改查功能。
系统分析与架构设计
在编码之前,我们需要明确系统中的核心对象及其交互关系:
- 数据模型层:需要
Book(书本信息)和BookShelf(书架容器)来管理图书资源。 - 用户管理层:系统存在两种角色——普通用户和超级管理员,他们拥有不同的菜单权限。
- 操作逻辑层:所有具体的业务操作(如借书、还书、删除)独立封装为模块,通过接口统一调用。
为了保持代码整洁,我们按照职责划分包结构:book 包负责数据,user 包负责用户类,operate 包负责具体功能实现。
第一步骤:实现数据模型 (book)
首先定义图书实体类 Book。该类用于封装书的属性,遵循封装原则,成员变量设为私有并提供 Getter/Setter 方法。为了支持初始化,添加一个构造方法。
package book;
public class Book {
private String name;
private String author;
private String type;
private int price;
// 借阅状态:true表示被借出,false表示在馆
private boolean borrow;
public Book() {}
public Book(String name, String author, String type, int price) {
this.name = name;
this.author = author;
this.type = type;
this.price = price;
this.borrow = false;
}
// 省略标准的 getter 和 setter 方法...
}
接着,我们需要一个容器来存放这些书。虽然实际项目中会使用数据库,但在此项目中我们使用 Book 类型的数组。创建一个 BookShelf 类作为书架管理容器:
package book;
public class BookShelf {
// 预定义最大容量为1000本书
private Book[] books = new Book[1000];
// 记录当前书架上的有效图书数量
private int count = 1;
public BookShelf() {
// 默认初始化一本书
books[0] = new Book("呐喊", "鲁迅", "小说集", 30);
}
// 设置指定位置的图书
public void setBooks(int pos, Book book) {
books[pos] = book;
}
// 获取指定下标的图书对象
public Book pos(int i) {
return books[i];
}
// 获取当前图书总数
public int getCount() {
return count;
}
// 更新图书总数
public void setCount(int count) {
this.count = count;
}
}
第二步骤:构建用户体系与多态 (user)
系统中包含“管理员”和“普通用户”两类用户。由于两者登录方式相似但后续功能不同,我们可以利用 Java 的多态特性:
- 定义一个抽象基类
User,包含用户名和菜单展示方法。 - 创建子类
AdminUser和NormalUser分别继承自User。
父类抽象代码片段:
public abstract class User {
private String name;
public IOperate[] ioperate; // 绑定该用户可执行的操作列表
public User(String name) {
this.name = name;
}
public abstract int menu(); // 返回选择的指令ID
// 根据用户选择的指令执行对应操作
public void chooseOperate(int choice, BookShelf bookShelf) {
// 安全检查:防止越界访问
if (choice >= 0 && choice < ioperate.length) {
ioperate[choice].work(bookShelf);
} else {
System.out.println("输入错误");
}
}
}
子类实现示例(以管理员为例,重点在于 ioperate 数组的赋值):
public class AdminUser extends User {
public AdminUser(String name) {
super(name);
// 管理员拥有的操作:退出、查找、新增、删除、显示
// 索引0通常预留或对应退出,需与实际菜单显示顺序保持一致
this.ioperate = new IOperate[] {
null, // index 0: placeholder for Exit or other
new FindBook(),
new AddBook(),
new DelBook(),
new DisplayBook()
};
}
@Override
public int menu() {
System.out.println("欢迎" + name + "管理员!");
System.out.println("1. 查找图书");
System.out.println("2. 新增图书");
System.out.println("3. 删除图书");
System.out.println("4. 显示图书");
System.out.println("0. 退出系统");
System.out.print("请输入你的选择: ");
Scanner scanner = new Scanner(System.in);
return scanner.nextInt();
}
}
普通用户 NormalUser 的实现类似,但其 ioperate 数组中应包含借书、还书等操作类。
第三步骤:实现功能操作 (operate)
为了实现业务逻辑的扩展性,我们定义一个操作接口 IOperate。所有的具体操作(如新增、删除)都实现这个接口。
package operate;
import book.BookShelf;
public interface IOperate {
void work(BookShelf bookShelf);
}
以“新增图书”功能 AddBook 为例,演示如何接收用户输入并更新书架:
package operate;
import book.Book;
import book.BookShelf;
import java.util.Scanner;
public class AddBook implements IOperate {
@Override
public void work(BookShelf bookShelf) {
System.out.println("请输入图书名字:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println("请输入作者:");
String author = scanner.nextLine();
System.out.println("请输入类型:");
String type = scanner.nextLine();
System.out.println("请输入价格:");
int price = scanner.nextInt();
Book book = new Book(name, author, type, price);
int currentCount = bookShelf.getCount();
// 存入数组,并增加计数
bookShelf.setBooks(currentCount, book);
bookShelf.setCount(currentCount + 1);
System.out.println("新增成功!");
}
}
对于其他操作(如 DelBook, BorrowBook),同样遵循此模式:获取用户输入 → 遍历 BookShelf 查找目标 → 修改对象状态 → 保存结果。
第四步骤:主程序入口与逻辑流转
在主程序中,我们通过循环模拟系统的持续运行。每次循环询问用户名及身份,实例化对应的 User 对象,然后进入操作循环。
import user.User;
import user.AdminUser;
import user.NormalUser;
import book.BookShelf;
public class Main {
public static void main(String[] args) {
BookShelf shelf = new BookShelf();
Scanner input = new Scanner(System.in);
while(true) {
System.out.print("请输入姓名: ");
String name = input.nextLine();
System.out.println("请选择身份: 1. 管理员 2. 普通用户");
int role = input.nextInt();
User currentUser = null;
if (role == 1) {
currentUser = new AdminUser(name);
} else {
currentUser = new NormalUser(name);
}
// 进入用户专属操作循环
while(true) {
int choice = currentUser.menu();
if (choice == 0) break;
currentUser.chooseOperate(choice, shelf);
}
}
}
}
注意事项与优化建议
- 内存泄漏问题:在编写退出功能时,建议遍历数组将引用置为
null,虽然 JVM 会在进程结束后自动回收,但在大型应用中这是良好的习惯。 - toString 重写:直接打印对象会输出内存地址。建议在
Book类中重写toString()方法,以便在列表中清晰展示图书信息。 - 数据校验:当前代码未对输入价格或书名做合法性检查,实际开发中需加入正则判断或非空校验。
以上就是Java实现图书管理系统的设计思路与代码细节,更多关于Java面向对象实战的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









