零基础入门Java之设计图书管理系统

在阅读本文章之前,建议读者优先阅读本专栏内前面的文章。


前言

本篇文章主要介绍如何运用专栏内前面的Java语法知识来设计一个简单的图书管理系统。


首先既然要设计一个图书管理系统我们就最先需要思考的就是它里面最基本的元素,也就是书,该怎么设计?要想设计书这个类,我们首先就是要思考它的特征是什么,比如说它最基本的书名、作者、价格、种类、是否借出等等,当然这是比较好设计的。我直接给出我的示例:

java 复制代码
package book;

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

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

    public String getName() {
        return name;
    }

    public String getAuthor() {
        return author;
    }

    public int getPrice() {
        return price;
    }

    public String getType() {
        return type;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ", isBorrowed=" + isBorrowed +
                '}';
    }
}

接下来,我们既然已经有书了,那么我们该如何去存放他们呢?在现实中,我们可以用书架来进行存放,但是在我们的整个系统中呢?显然,我们最好的选择就是数组这个结构。那么我们也就可以定义一个书架类,来方便我们针对书本的一系列操作。目前来说,我们这个书架类需要完成的就是存储图书,并且了解当前架上的图书的本数,那么我们就可以有如下的定义:

java 复制代码
package book;

public class BookList {
    private Book[] books = new Book[100];
    private int usedSize;
    public BookList(){
        this.books[0] = new Book("三国演义","罗贯中",10,"小说");
        this.books[1] = new Book("西游记","吴承恩",59,"小说");
        this.books[2] = new Book("红楼梦","曹雪芹",16,"小说");

        this.usedSize = 3;
    }
}

好了,既然是一个管理系统,我们肯定就要有用户,但是用户我们肯定要有普通用户和管理员用户的区别,为了方便,我们就先创建一个用户父类,然后再分别进行继承完成特定用户的需求即可。我们就可以有如下的定义:

java 复制代码
package user;

public abstract class User {
    protected String name;

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

然后我们再分别来实现这两类用户,在实现他们的时候,我们顺便思考一下二者需要的功能,我给出示例:

java 复制代码
package user;

import java.util.Scanner;

public class AdminUser extends User{
    public AdminUser(String name) {
        super(name);
    }
    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("********************");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的操作: ");
        int choice = scanner.nextInt();
    }
}
java 复制代码
package user;

import java.util.Scanner;

public class NormalUser extends User{
    public NormalUser(String name) {
        super(name);
    }
    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("*******************");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的操作: ");
        int choice = scanner.nextInt();
    }
}

这段代码首先通过import语句引入user包下的User父类及其子类AdminUser、NormalUser,然后在 Main类中定义了login()静态方法,该方法利用Scanner获取用户输入的姓名和身份选择(1为管理员、2为普通用户),并根据选择创建并返回对应的AdminUser或NormalUser子类对象;main()方法作为程序入口,先调用login()方法完成用户登录并得到用户对象,再调用该对象的menu()方法,此时会根据对象的实际类型自动执行子类重写后的menu()方法,实现管理员和普通用户展示不同菜单的差异化行为。运行后其结果如下:

然后我们就可以去实现这些具体的方法了,但是在实现之前,我们可以先把这些框架先搭建好,确定没有问题之后我们再去填充具体的功能。那么我们该如何去搭建这个方法的框架呢?我们可以发现实际上这些方法都是极为类似的,因为他们实际上都是针对我们的书架类进行操作,那么我们就可以去实现一个接口,之后对于接口中的方法进行重写,进而去实现一系列的操作。也就是如下的操作:

java 复制代码
package ioperations;

import book.BookList;

public interface IOperation {
    public void work(BookList bookList);
}

接下来,我们就可以通过对方法进行重写来实现我们这些具体的方法了:

java 复制代码
package ioperations;

import book.BookList;

public class AddOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("增加图书...");
    }
}
java 复制代码
package ioperations;

import book.BookList;

public class BorrowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书...");
    }
}
java 复制代码
package ioperations;

import book.BookList;

public class DelOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书...");
    }
}
java 复制代码
package ioperations;

import book.BookList;

public class ExitOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统...");
    }
}
java 复制代码
package ioperations;

import book.BookList;

public class FindOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("查找图书...");
    }
}
java 复制代码
package ioperations;

import book.BookList;

public class ReturnOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书...");
    }
}
java 复制代码
package ioperations;

import book.BookList;

public class ShowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("展示图书...");
    }
}

好了,现在这些方法的框架已经搭建完成了,那么我们知道,我们的基本思路是通过选择特定的数字来选择我想要访问的方法,那么我们有这么多的方法,当然可以通过选择语句来访问不同的分支,但是相对来说这样会比较麻烦。干脆我们就在User这个父类之中定义一个专门存储操作方法的数组,然后根据需要进行访问即可,也就是如下的代码:

java 复制代码
package user;

import book.BookList;
import ioperations.IOperation;

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){
        iOperations[choice].work(bookList);
    }
}

然后在两类用户之中,我们分别存储其需要用到的方法,也就是如下:

java 复制代码
package user;

import ioperations.*;

import java.util.Scanner;

public class AdminUser extends User{
    public AdminUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{
            new ExitOperation(),
            new FindOperation(),
            new AddOperation(),
            new DelOperation(),
            new ShowOperation()
        };
    }
    public int 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("********************");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的操作: ");
        int choice = scanner.nextInt();
        return choice;
    }
}
java 复制代码
package user;

import ioperations.*;

import java.util.Scanner;

public class NormalUser extends User{
    public NormalUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }
    public int menu(){
        System.out.println("******用户菜单******");
        System.out.println("*****1.查找图书*****");
        System.out.println("*****2.借阅图书*****");
        System.out.println("*****3.归还图书*****");
        System.out.println("*****0.退出系统*****");
        System.out.println("*******************");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的操作: ");
        int choice = scanner.nextInt();
        return choice;
    }
}

然后我们就可以运行如下的代码:

java 复制代码
import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;

import java.util.Scanner;

public class Main {
    public static User login() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的姓名: ");
        String name = scanner.nextLine();

        System.out.println("请输入您的身份: 1.管理员  2.用户");
        int choice = scanner.nextInt();
        if (choice == 1) {
            return new AdminUser(name);
        }else{
            return new NormalUser(name);
        }
    }

    public static void main(String[] args) {
        BookList bookList = new BookList();
        User user = login();
        while (true){
            int choice = user.menu();
            user.doIOperation(choice, bookList);
        }
    }
}

其运行的结果如下:

好了,那么我们现在整个框架的搭建就完成了,我们就可以来实现具体的功能了。首先最好实现的功能就是退出整个图书系统,我们就是如下的代码:

java 复制代码
package ioperations;

import book.BookList;

public class ExitOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统...");
        System.exit(0);
    }
}

其运行结果如下:

然后我们再接着来实现一下展示图书的功能,我们可以用一种很简单的方式,也就是借用for循环遍历来实现:

java 复制代码
package ioperations;

import book.Book;
import book.BookList;

public class ShowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("展示图书...");
        Book[] books = bookList.getBooks();
        for(int i = 0; i < bookList.getUsedSize(); i++){
            System.out.println(books[i].toString());
        }
    }
}

其运行的结果如下:

但是为了更好的实现功能,我们采用如下这种形式来实现功能,我们首先在BookList类中写入如下的方法:

java 复制代码
public Book getBook(int pos) {
    return books[pos];
}

public void setBook(int pos,Book book) {
    this.books[pos] = book;
}

然后回到展示图书的功能中,键入如下的代码:

java 复制代码
package ioperations;

import book.Book;
import book.BookList;

public class ShowOperation implements IOperation {
    @Override
    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);
        }
    }
}

它也会达到与刚刚相同的效果。我们接下来再来尝试实现一下查找图书的方法。其实它就是需要我们输入特定的图书名称,之后遍历库内所有的图书并且一一对比,如果说成功找到的话就给出图书信息的输出,我给出示例代码如下:

java 复制代码
package ioperations;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class FindOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("查找图书...");
        Scanner scanner =  new Scanner(System.in);
        System.out.println("请输入想要查找的图书名字: ");
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for(int i = 0; i < currentSize; i++){
            Book book = bookList.getBook(i);
            if(book.getName().equals(name)){
                System.out.println("已找到这本书");
                System.out.println(book);
                return;
            }
        }
        System.out.println("未找到这本书");
    }
}

其运行结果如下:

我们这时发现后面的这个判断是否借出的属性其实我们可以让他更容易看一些,所以我们可以在Book类中作出如下的改动:

java 复制代码
package book;

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

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

    public String getName() {
        return name;
    }

    public String getAuthor() {
        return author;
    }

    public int getPrice() {
        return price;
    }

    public String getType() {
        return type;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

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

我们再次运行一下功能,其运行结果如下:

好了,我们接下来再来看看如何去实现增添图书这个功能,分析一下,其实整个过程就是如下这样,输入各种成员变量来构建对象,然后判断书架是否满了,没满的话就放到书架的最后一个位置,然后让usedSize自增就好了。我们首先需要先在BookList类中添加一些方法:

java 复制代码
package book;

public class BookList {
    private Book[] books = new Book[100];
    private int usedSize;
    public BookList(){
        this.books[0] = new Book("三国演义","罗贯中",10,"小说");
        this.books[1] = new Book("西游记","吴承恩",59,"小说");
        this.books[2] = new Book("红楼梦","曹雪芹",16,"小说");

        this.usedSize = 3;
    }

    public int getUsedSize() {
        return usedSize;
    }

    public Book getBook(int pos) {
        return books[pos];
    }

    public void setBook(int pos,Book book) {
        this.books[pos] = book;
    }

    public Book[] getBooks() {
        return books;
    }

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

然后我们继续完善这个增添图书的方法:

java 复制代码
package ioperations;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class AddOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("增加图书...");
        int currentSize = bookList.getUsedSize();
        if(currentSize == bookList.getBooks().length){
            System.out.println("书架满了");
        }
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入图书的名字: ");
        String name = scanner.nextLine();
        System.out.println("请输入图书的作者: ");
        String author = scanner.nextLine();
        System.out.println("请输入图书的价格: ");
        int price = scanner.nextInt();
        scanner.nextLine();
        System.out.println("请输入图书的种类: ");
        String type = scanner.nextLine();
        Book newbook = new Book(name, author, price, type);
        for(int i = 0; i < currentSize; i++){
            Book book = bookList.getBook(i);
            if(book.getName().equals(name)){
                System.out.println("架上已有这本书,不可插入");
                System.out.println(book);
                return;
            }
        }
        bookList.setBook(currentSize, newbook);
        bookList.setUsedSize(currentSize + 1);
        System.out.println("插入图书成功");
    }
}

其运行结果如下:

然后我们再来查看一下我们是否插入进来了这本书:

在完成这个功能之后,我们再来看看如何实现归还图书的功能,我们首先需要在Book类中增添一些内容:

java 复制代码
package book;

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

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

    public String getName() {
        return name;
    }

    public String getAuthor() {
        return author;
    }

    public int getPrice() {
        return price;
    }

    public String getType() {
        return type;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

    public void setBorrowed(boolean borrowed) {
        isBorrowed = borrowed;
    }

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

然后我们就可以继续完善此功能的代码:

java 复制代码
package ioperations;

import book.BookList;

import java.util.Scanner;

public class BorrowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书...");
        System.out.println("请输入您要借阅的书的名字: ");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for(int i = 0; i < currentSize; i++){
            if(bookList.getBook(i).isBorrowed()){
                System.out.println("此书已被借阅");
                return;
            }
            if(bookList.getBook(i).getName().equals(name)){
                System.out.println("找到了这本书");
                bookList.getBook(i).setBorrowed(true);
                System.out.println("借阅成功");
                return;
            }
        }
        System.out.println("没有你要找的这本书");
    }
}

其运行结果如下:

然后我们再来实现归还书的方法,本质上它与借书逻辑相似,我们键入如下的代码:

java 复制代码
package ioperations;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class ReturnOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要归还的书的名字: ");
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for(int i = 0; i < currentSize; i++){
            Book book = bookList.getBook(i);
            if(book.getName().equals(name)){
                book.setBorrowed(false);
                System.out.println("归还成功");
                return;
            }
        }
        System.out.println("没有这本书");
    }
}

我们刚刚借阅了三国演义这本书,我们接下来尝试归还来验证我们方法的正确性:

最后就是删除其中的书:

java 复制代码
import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;

import java.util.Scanner;

public class Main {
    public static User login() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的姓名: ");
        String name = scanner.nextLine();

        System.out.println("请输入您的身份: 1.管理员  2.用户");
        int choice = scanner.nextInt();
        if (choice == 1) {
            return new AdminUser(name);
        }else{
            return new NormalUser(name);
        }
    }

    public static void main(String[] args) {
        BookList bookList = new BookList();
        User user = login();
        while(true){
            int choice = user.menu();
            user.doIOperation(choice, bookList);
        }
    }
}

其运行结果如下:

那么到这,我们的一个简单的图书管理系统接完成了。


总结

本文介绍了如何使用Java实现一个简单的图书管理系统。系统包含Book类存储图书信息(书名、作者等),BookList类管理图书数组,以及区分管理员和普通用户的User类体系。通过接口IOperation定义操作规范,实现了图书查找、借阅、归还、新增、删除等功能。系统采用面向对象设计,通过继承和多态实现不同用户菜单的差异化展示。文章详细展示了各类代码实现,包括图书状态管理、用户操作交互等核心功能,最终完成了一个具备基本功能的图书管理系统原型。

相关推荐
巴拉巴拉~~2 小时前
Flutter 通用滑块组件 CommonSliderWidget:单值 / 范围 + 刻度 + 标签 + 样式自定义
开发语言·前端·javascript
墨雪不会编程2 小时前
C++内存管理深度剖析
java·开发语言·c++
BBB努力学习程序设计2 小时前
Java Scanner完全指南:让程序与用户对话
java
BBB努力学习程序设计2 小时前
Java面向对象编程:封装、继承与多态深度解析
java
Lucky_Turtle2 小时前
【Springboot】解决PageHelper在实体转Vo下出现total数据问题
java·spring boot·后端
Mr.朱鹏2 小时前
大模型入门学习路径(Java开发者版)下
java·python·学习·微服务·langchain·大模型·llm
期待のcode2 小时前
验证码实现
java·vue.js
老华带你飞2 小时前
志愿者服务管理|基于springboot 志愿者服务管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
汤姆yu2 小时前
基于springboot的宠物服务管理系统
java·spring boot·后端