Java项目 简易图书管理系统

面向对象是Java中最重要的思想,本图书管理系统就是以面向对象为中心,逐层拆解业务。

首先抽象出对象,一想到图书管理系统,我们就会想到 书和 能操作书的人 。

但只有书还不够 还需要 一个书架 来进行管理

那么 总结 下来

我们需要创建 书类(Book) 、管理书的书架类(BookList)、用户类(User)

每个事物都有自己的属性,那么我们就需要考虑 这三个类 都有什么成员属性和成员方法


自定义类

  1. Book类

成员属性:书名(name),作者名(author),价格(price),类型(type),是否被借出的状态(state)

构造方法:初始化Book

成员方法:因为我们不希望外界干扰这些关键信息,因此都需要用 private 修饰。因此每个成员属性都要有 get 和 set 方法

  1. BookList类

书架上需要放很多的书,那么书籍的底层数据结构用数组最合适不过了

成员属性:书架(Book\[\] books),书架的长度(usedSize)

构造方法:初始化Books (默认有三本书)

成员方法:因为我们不希望外界干扰这些关键信息,因此都需要用 private 修饰。因此每个成员属性都要有 get 和 set 方法

  1. User类

对于用户来说 要 分为 管理权限高的 管理员和 权限比较低的 普通用户。

管理员的权限功能: 显示图书、增加图书、删除图书、查询图书、退出系统

普通用户的权限功能:查询图书、借阅图书、归还图书、退出系统

那么我们要根据用户的不同来分别呈现对应的菜单功能,因此我们需要借助多态的思想。

但实现多态的前提,需要继承,因此我们需要有User这个大类,并让普通用户(NomralUser)和 管理员(AdminUser) 继承User。

成员属性:姓名(name)

构造方法:初始化name

成员方法:菜单选项(menu)

因为用户不同,所以对应的菜单打印也不同,因此 NomralUser 和 AdminUser类 也都需要重写父类的 menu方法。那么 menu 方法 应该由 abstract 修饰 并且 User类也不能用来具体表示某个对象只是泛称因此也要用 abstract 修饰。


自定义接口

因为 NomralUser 和 AdminUser 对于的菜单操作方法不同,我们可以创建接口数组,利用接口数组组织这些操作,需要用到哪个直接按照用户输入的数字,调用出对应数组下标的操作方法。

但接口并不能直接创建和实现, 因此 我们需要对每个操作都创建对应的类 然后 将这些类实现接口。

"管理员" 需要的操作:显示图书信息、增加图书信息、删除图书信息、查询图书信息、退出系统
"用户" 需要的操作:查询图书信息、借阅图书、归还图书、退出系统

这些操作,分别定义成 :
"Add" 增加
"Delete" 删除
"Show" 显示
"Find" 查找
"Borrow" 借阅
"Return" 归还
"Exit" 退出

让这些 都 实现Operation 这个接口,在 Operation 接口中 定义一个抽象方法: work() ,这样就只需要在这些 中重写 **work()**方法即可


代码书写

我们根据上面的这些 分析,进行编写代码

book 包

创建一个 book包 里面有 Book类 和 BookList类

Book类

java 复制代码
package book;

public class Book {
    private String name;
    private String author;
    private int price;
    private String type;
    private boolean state;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean isState() {
        return state;
    }

    public void setState(boolean state) {
        this.state = state;
    }

    public Book(String name, String author, int price, String type) {
        this.name = name;
        this.author = author;
        this.price = price;
        this.type = type;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                (state == true ? "已借出": "未借出") +
//                ", state=" + state +
                '}';
    }


}

可以看到构方法中没有 state 这个参数,是因为 boolean 类型的变量即使不初始化,系统也会赋给一个默认值,默认为 "false"

BookList类

java 复制代码
package book;

public class BookList {

    private Book[] books = new Book[10];
    private int usedSize;

    public BookList(Book[] books, int usedSize) {
        books[0] = new Book("铁道概论","张三",10,"教科书");
        books[1] = new Book("电路分析基础","李四",15,"教科书");
        books[0] = new Book("区间闭塞设备维修","王五",20,"教科书");
        this.usedSize = 3;
    }

    public int getUsedSize() {
        return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }
}
}

创建书架时,默认书架上有三本书


user包

创建一个user包,里面分别有 User 父类,继承User的子类 NomralUser 和 AdminUser类

User类

java 复制代码
package user;

//因为User不能表达某个具体的对象
//并且有抽象方法,因此为抽象类

import book.BookList;

public abstract class User {
    protected String name;
    protected IOPeration[] ioPerations;//接口数组 分别放置不同的操作

    public User(String name) {
        this.name = name;
    }

    //抽象方法的原因,根据子类各自的情况,呈现不同的菜单详情,因此父类 menu 方法 不用有具体实现
    public abstract int menu();

}

AdminUser 子类

java 复制代码
package user;

public class AdminUser extends User{

    public AdminUser(String name) {
        super(name);
    }

    @Override
    public void menu() {
        System.out.println("------------管理员菜单------------");
        System.out.println("1.查找图书");
        System.out.println("2.新增图书");
        System.out.println("3.删除图书");
        System.out.println("4.显示图书");
        System.out.println("0.退出系统");
        System.out.println("------------------------------------------------");
    }
}

NomralUser 子类

java 复制代码
public class NomralUser extends User{


    public NomralUser(String name) {
        super(name);
    }

    @Override
    public void menu() {
        System.out.println("------------普通用户菜单------------");
        System.out.println("1.查找图书");
        System.out.println("2.借阅图书");
        System.out.println("3.归还图书");
        System.out.println("0.退出系统");
        System.out.println("------------------------------------------------");
    }

}

operation包

存放接口 IOPeration,和其他操作类

添加图书:AddOperation

借阅图书:BorrowedOpreation

删除图书:DelOperation

退出系统:ExitOpreation

寻找图书:FindOperation

归还图书:ReturnOpreation

显示图书:ShowOperation

接口 IOPeration

java 复制代码
package operation;

import book.BookList;


public interface IOPeration {
    void work(BookList booklist);
}

AddOperation类

java 复制代码
public class AddOperation implements IOperation{

    @Override
    public void work() {

    }
}

BorrowedOpreation类

java 复制代码
public class BorrowedOpreation implements IOperation{
    @Override
    public void work() {

    }
}

DelOperation类

java 复制代码
public class DelOperation implements IOperation{
    @Override
    public void work() {

    }
}

ExitOpreation类

java 复制代码
public class ExitOpreation implements IOperation{
    @Override
    public void work() {

    }
}

FindOperation类

java 复制代码
public class FindOperation implements IOperation{
    @Override
    public void work() {

    }
}

ReturnOpreation类

java 复制代码
public class ReturnOpreation implements IOperation {
    @Override
    public void work() {

    }
}

ShowOperation类

java 复制代码
public class ShowOperation implements IOperation{
    @Override
    public void work() {

    }
}

基本准备工作准备好了之后,我们就要代入操作者的视角,进行操作内容的搭建

  1. 登录系统

  2. 选择身份

  3. 选择想要进行的操作

程序入口

我们可以在src包下创建一个Main类,作为程序的入口

Main类

java 复制代码
public static User login(){
        System.out.println("请输入你的姓名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();

        System.out.println("请选择你的身份 1-> 管理员 2-> 普通用户");

        int choice = scanner.nextInt();
        if(choice == 1){
            AdminUser adminUser = new AdminUser(name);
            return adminUser;
        } else{
            NomralUser nomralUser = new NomralUser(name);
            return nomralUser;
        }

    }


    public static void main(String[] args) {

        //第一步 创建书架
        BookList bookList = new BookList();
        //第二步 根据输入,获取用户权限信息
        //向上转型
        User user = login();

我们根据输入的数字进入new对应身份的对象,然后用 User父类引用对象 接收,这里就是向上转型,并为下面根据 不同的身份打印不同的菜单(多态)提供了前提条件

java 复制代码
public static User login(){
        System.out.println("请输入你的姓名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();

        System.out.println("请选择你的身份 1-> 管理员 2-> 普通用户");

        int choice = scanner.nextInt();
        if(choice == 1){
            AdminUser adminUser = new AdminUser(name);
            return adminUser;
        } else{
            NomralUser nomralUser = new NomralUser(name);
            return nomralUser;
        }

    }


    public static void main(String[] args) {

        //第一步 创建书架
        BookList bookList = new BookList();
        //第二步 根据输入,获取用户权限信息
        //向上转型
        User user = login();
        //第三步 利用多态思想 打印对应菜单 并获取 选项
        int choice = user.menu();

    }

接下来我们只剩下对 操作的处理

因为 管理员 和 普通用户 既有相同操作又有不同的操作,那么我们就需要用接口数组。在数组中存放相应的操作,当用户输入操作数字,我们只需根据输入 将数组对应下标的方法调用即可。

所以我们在 User 父类中:

补充一个成员属性:IOperations 数组,只声明即可,在子类中利用构造方法帮助父类进行初始化这个数组

补充一个成员方法: doIoperation(),利用下标访问对应的类中的 work 方法

补充 User 父类

java 复制代码
public abstract class User {
    protected String name;

    //新增
    protected IOperation[] ioPerations;

    public User(String name) {
        this.name = name;
    }

    public abstract int menu();

    //新增
    public void doIoperation(int choice, BookList booklist) {
        this.ioPerations[choice].work(booklist);
    }

}

补充子类的构造方法

java 复制代码
public AdminUser(String name) {
        super(name);
        this.ioPerations = new IOPeration[]{
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DelOperation(),
                new ShowOpreation()

        };
    }
java 复制代码
public NormalUser(String name) {
        super(name);
        this.ioPerations = new IOPeration[]{
                new ExitOperation(),
                new FindOperation(),
                new BorrowedOperation(),
                new ReturnOperation()
        };
    }

根据构造方法,就可以初始化数组了

最后补全方法调用语句 user.doIoperation();

java 复制代码
public static void main(String[] args) {

        //第一步 创建书架
        BookList bookList = new BookList();
        //第二步 根据输入,获取用户权限信息
        //向上转型
        User user = login();
        //第三步 利用多态思想 打印对应菜单 并获取 选项
        int choice = user.menu();

        //调用方法 体现了动态绑定

        user.doIoperation(choice,bookList);

    }

最后我们只剩具体操作的核心逻辑了

补全操作

AddOperation类

java 复制代码
public class AddOperation implements IOPeration{
    public void work(BookList bookList){
        System.out.println("新增图书");

        if(bookList.isFull()){
            System.out.println("书架满了 不能新增了");
            return;
        }

        System.out.println("请输入你要新增的图书的书名");
        Scanner scanner = new Scanner(System.in);
        String bookName = 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(bookName,author,price,type);
        //在数组的末尾加入数据

        int currentSize = bookList.getUsedSize();
        bookList.setBook(currentSize,book);
        bookList.setUsedSize(currentSize+1);
        System.out.println("新增图书成功!");


    }
}

BorrowedOperation类

java 复制代码
public class BorrowedOperation implements IOPeration{
    public void work(BookList bookList){
        System.out.println("借阅图书");

        System.out.println("请输入你想要借阅的图书");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();
        int currentSize = bookList.getUsedSize();

        for (int i = 0; i < currentSize; i++) {

            Book book = bookList.getBook(i);
            if(book.getName().equals(bookName)){
                book.setState(true);
                System.out.println("借阅成功");
                return;
            }
        }

        System.out.println("借阅失败");
    }
}

DelOperation类

java 复制代码
public class DelOperation implements IOPeration{
    public void work(BookList bookList){
        System.out.println("删除图书");

        System.out.println("请输入你要删除的图书的书名: ");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();

        int currentSize = bookList.getUsedSize();
        //初始化下标
        int pos = -1;
        int i = 0;
        for (; i < currentSize; i++) {

            Book book = bookList.getBook(i);
            if (book.getName().equals(bookName)){
                //代码执行到这里时,已经说明 找到了这本书
                //记录下标
                pos = i;
                break;
            }


        }
        if (i >= currentSize){
            System.out.println("没有你要删除的图书");
            return;
        }

        //开始删除
        for(int j = pos; j < currentSize - 1;j++){
            bookList.setBook(j,bookList.getBook(j+1));
//           Book book = bookList.getBook(j+1);
//           bookList.setBook(j,book);
        }

        //删除之后,修改usedSize
        bookList.setUsedSize(currentSize-1);
        bookList.setBook(currentSize-1 ,null);

    }
}

ExitOperation类

java 复制代码
public class ExitOperation implements IOPeration{
    public void work(BookList bookList){
        System.out.println("退出系统");

        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            bookList.setBook(i,null);
        }


        // 0 代表正常退出
        System.exit(0);
    }
}

FindOperation类

java 复制代码
public class FindOperation implements IOPeration{
    public void work(BookList bookList){
        System.out.println("寻找图书");
        System.out.println("请输入你要查找的图书名:");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();

        int currentSize = bookList.getUsedSize();

        for(int i = 0; i < currentSize; i++){
            Book book = bookList.getBook(i);
            if(book.getName().equals(bookName)){
                System.out.println("找到了这本书:");
                System.out.println(book);
                //因为重写了Book 的 toString 方法
                return;
            }
        }

        System.out.println("没有你要找的书");


    }
}

ReturnOperation类

java 复制代码
public class ReturnOperation implements IOPeration{
    public void work(BookList bookList){
        System.out.println("归还图书");

        System.out.println("请输入你想要归还的图书");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();
        int currentSize = bookList.getUsedSize();

        for (int i = 0; i < currentSize; i++) {

            Book book = bookList.getBook(i);
            if(book.getName().equals(bookName)){
                book.setState(false);
                System.out.println("归还成功");
                return;
            }
        }

        System.out.println("归还失败");
    }

}

ShowOpreation类

java 复制代码
public class ShowOpreation implements IOPeration{
    public void work(BookList bookList){
        System.out.println("显示图书");

        int currentSize = bookList.getUsedSize();
        for(int i = 0;i < currentSize; i++){
            Book book = bookList.getBook(i);
            System.out.println(book);
        }
    }
}
相关推荐
Scott9999HH36 分钟前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔43 分钟前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨3 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区5 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai6 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说6 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json