Bootstrap

【Java】实现图书管理系统

前言:

对于图书管理系统,小编进行了一次完整的模拟,小编将从我的思路尽量将过程呈现出来,希望能够帮到屏幕前的你。^ . ^

 1.实现结果

在图书管理系统中,我们规定两类用户,普通用户以及管理员。他们分别执行各自的功能项目。

欢迎GGBondlctrl来到管理员菜单
------------------
1.查找图书
2.新增图书
3.删除图书
4.显示图书
0.退出系统
------------------

 欢迎GGBondlctrl来到普通成员菜单
------------------
1.查找图书
2.借阅图书
3.归还图书
0.退出系统
------------------

通过输入对应用户的对应的数值,可以进行添加,删除,显示等操作。

例如:管理员菜单的新增书籍示范:

 请输入你的操作
2
新增书籍
请输入书名:
红楼梦
请输入作者:
曹雪芹
请输入价格:
56
请输入书的类型:
小说
已经成功添加你的书籍

再次输入显示书籍的指令,就会发现书籍已经添加进去了

请输入你的操作
4
显示书籍
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=未被借出}
Book{bookName='水浒传', author='施耐庵', price=59, types='小说', isBorrow=未被借出}
Book{bookName='三国演义', author='罗贯中', price=67, types='小说', isBorrow=未被借出}
Book{bookName='红楼梦', author='曹雪芹', price=54, types='小说', isBorrow=未被借出} 

此时我们发现我们添加的《红楼梦》已经添加进去了。

 2.功能的分类

1.小编在这里分了三个包来进行功能的分类,非别是Book,Operation,User。既然是图书管理,那么就有书,和书架,所以小编设置了book包,如上图显示,功能为一个包,用户一个包。

在book包里,小编设置了book类来存储成员变量的声明,以及booklist来表示书架来存书籍,操作包里就是各个操作,用户包里就进行两者用户的编写,以及主函数。

3.代码实现过程

3.1.book类

在book类中我们肯定要进行图书属性的声明,因为是封装所以小编这里使用了private修饰符修饰成员变量,这里注意借出与不借出,小编这里默认的是为false为没有被借出。

代码如下:

public class Book {
    private String bookName;
    private String author;
    private int price;
    private  String types;
    private boolean isBorrow;

    public Book(String bookName, String author, int price, String types, boolean isBorrow) {
        this.bookName = bookName;
        this.author = author;
        this.price = price;
        this.types = types;
        this.isBorrow = isBorrow;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    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 getTypes() {
        return types;
    }

    public void setTypes(String types) {
        this.types = types;
    }

    public boolean isBorrow() {
        return isBorrow;
    }

    public void setBorrow(boolean borrow) {
        isBorrow = borrow;
    }

    
}

这里小编还进行了构造函数的声明,以及get与set函数,通过快捷键alt+insert来进行编写, 

 (为啥要用get与set函数):因为我们的成员变量是私有的,要想使用就得传入set函数通过get函数来调用对应的成员变量。

3.2.booklist类

在此类中小编创建了一个Book类的books的数组对象。在构造函数中存入了三本书分别在,0,1,2,下标。

public class Booklist {
    Book []books=new Book[10];
    private int sizeBook;
    public Booklist(){
        this.books[0]= new Book("西游记","吴承恩",57,"小说",false);
        this.books[1]= new Book("水浒传","施耐庵",59,"小说",false);
        this.books[2]=new Book("三国演义","罗贯中",67,"小说",false);
        sizeBook=3;
    }

这里还要设置数组的长度,,以及取书和拿书的方法,方便之后的操作类进行对应的操作

 public int getSizeBook() {
        return sizeBook;
    }
    public void setSizeBook(int sizeBook) {
        this.sizeBook = sizeBook;
    }
    public Book getBook(int indexBook){
        return books[indexBook];
    }
    public void setBook(int indexBook,Book book){
        books[indexBook]=book;

    }

注意:取书是getbook返回的类型是Book类型,通过输入下标值,返回对应的书籍信息。

存书也是一样的,通过输入下标以及存入的书,来完成对应位置房对应的书。

3.3.操作类

在操作类中,我们先在各个类实现work方法输出打印的方法,由于都存在一样的方法,就可以设置一个接口,其他类来实现这个接口。

public class borrowBook implements Ioperation {
    @Override
    public void work(Booklist booklist) {
        System.out.println("请输入你要借的书名:");

例如,我们将这借书的操作先输出出来,其他过程之后完善。其他操作类似;

以及接口:

public interface Ioperation {
    void work(Booklist booklist);

}

那么我们的操作类就先放在这里,进入下一个类。

3.4.用户类

1.在管理员类中,我们要实现输入名字,以及输入相关的数字进行对应操作方法的打印实现,

Scanner sc=new Scanner(System.in);
    public Administor(String name){
        super(name);
        this.ioperation=new Ioperation[]{new exitBook(),new selectBook(),new addBook(),new deletBook()
        ,new showBook() };
    }

    public int meau(){
        System.out.println("欢迎"+name+"来到管理员菜单");
        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("------------------");
        System.out.println("请输入你的操作");
        int num=sc.nextInt();
        return num;
    }
    public void open(int choice,Booklist booklist){
        ioperation[choice].work(booklist);
    }

1. 小编这里用scanner函数实现输入名字。

2.为啥构造函数里有super呢,因为小编这里是将管理员类继承于User父类,实现父类构造方法的重写,这里后面再说

3.这里通过接口类实现将各个功能通过数组存储。(这里是个向上转型)要看输入的数值来对应各对象功能的下标。

4.菜单方法,是为了方便了解对应数字的功能。

5.open方法的参数是输入的数字,以及书架;这里通过ioperation接收传递的数,来表对应的new操作对象,又通过操作对象实现对应的操作work。

例如:加入输入1,则通过上面:

this.ioperation=new Ioperation[]
{new exitBook(),new selectBook(),new addBook(),new deletBook(),new showBook() };

发现,对应的是new exitBook则再次调用它的work方法

public class exitBook implements Ioperation
{
    @Override
    public void work(Booklist booklist) {
        System.out.println("退出系统");
        System.exit(0);
    }
}

就完成了对应操作的交互响应

2. 在普通用户类也是一样的:

public class Nomaluser extends User{
    Scanner sc=new Scanner(System.in);
    public Nomaluser(String name){
        super(name);
        this.ioperation=new Ioperation[]{
                new exitBook(),
                new selectBook(),
                new borrowBook(),
                new leadBook()
        };
    }
    public int meau(){
        System.out.println("欢迎"+name+"来到普通成员菜单");
        System.out.println("------------------");
        System.out.println("1.查找图书");
        System.out.println("2.借阅图书");
        System.out.println("3.归还图书");
        System.out.println("0.退出系统");
        System.out.println("------------------");
        System.out.println("请输入你的操作");
        int num=sc.nextInt();
        return num;
    }
    public void open(int choice,Booklist booklist){
        ioperation[choice].work(booklist);
    }
}

这里要注意两者的操作不一样。

3.这里就是User父类的实现了,小编在上述的super和this.ioperation都有了很好的解释,

public abstract class User {
    Ioperation ioperation[];
    public String name;
    public User(String name){
        this.name=name;
    }
    abstract int meau();
    abstract void open(int choice, Booklist booklist);


}

这里声明了一个Ioperation类的ioperation的数组,就有了子类的各个功能的实现,这里设置了一个父类的有参构造方法,实现名字的打印,那么子类就应该进行重写。meau和open都是抽象方法,那么子类都应该重写。

3.5.主函数

代码如下:

public class Main {
    public static User logn() {

        Scanner sc=new Scanner(System.in);

        System.out.println("请输入你的名字:");
        String name=sc.nextLine();
        System.out.println("请输入你的身份1--》管理员,2--》普通用户");
        int choice=sc.nextInt();
        if (choice==1){
            Administor administor=new Administor(name);
            return administor;
        }
        else {
            Nomaluser nomaluser=new Nomaluser(name);
            return nomaluser;
        }
    }
    public static void main(String[] args) {
        Booklist booklist=new Booklist();
        User user=logn();
        while (true){
            int choice= user.meau();
            user.open(choice,booklist);
        }

    }
}

注意:1.小编在这里重写了一个静态方法,通过输入的值来判定对应的身份,如果是1,那么就是管理身份,返回管理的对象,如果是2,那么就返回普通用户的对象,那么我们应该用啥来接收呢,此时就要用一个向上转型的思想,我们就用父类User类来接收他们的对象,然后通过主函数入口,将对象给user,通过user来调用对应的open方法。这里还得有booklist的对象的声明。

4.代码实现完善

在上述过程中我们只是完成对应功能的打印。

例如:

请输入你的名字:
GGBondlctrl
请输入你的身份1--》管理员,2--》普通用户
1
欢迎GGBondlctrl来到管理员菜单
------------------
1.查找图书
2.新增图书
3.删除图书
4.显示图书
0.退出系统
------------------
请输入你的操作
1
查找书籍

那么接下来就要进行对应操作的功能的完善。

4.1.新增书籍

代码如下:

public class addBook implements Ioperation {
    @Override
    public void work(Booklist booklist) {
        System.out.println("新增书籍");
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入书名");
        String name= sc.nextLine();
        System.out.println("请输入作者");
        String author= sc.nextLine();
        System.out.println("请输入价格");
        int price=sc.nextInt();
        sc.nextLine();
        System.out.println("请输入书的类型");
        String type=sc.nextLine();
        Book book=new Book(name,author,price,type,false);
        int size=booklist.getSizeBook();
        booklist.setBook(size,book);
        size++;
        booklist.setSizeBook(size);
        System.out.println("已经成功添加你的书籍");
    }
}

在这里我们需要输入对应的作者,书籍名字,价格等等(注意:在nextInt方法会留下回车键或者换行符在输入流中,nextLine()会当做一行内容读取,所以解决办法时在之前在加一行nextLine消耗掉多于的换行符或回车键。)在将输入的内容传入book对象中去。通过size表示多少本书,在setBook方法中存书(位置,以及book这本书)默认的是存在数组的末尾。然后size加一,成为下一个存书的下标。

4.2.借阅书籍

代码如下:

public void work(Booklist booklist) {
        System.out.println("请输入你要借的书名:");
        Scanner sc=new Scanner(System.in);
        String name=sc.nextLine();
        int size= booklist.getSizeBook();
        for (int i = 0; i <size-1 ; i++) {
            Book book=booklist.getBook(i);
            if (book.getBookName().equals(name)){
                if(book.isBorrow()==true){
                    System.out.println("这本书已经被借出了");
                    break;
                }
                System.out.println("找到了你要借阅的书籍");
                book.setBorrow(true);
                break;
            }
        }

首先我们要通过输入书名,然后再“书架上遍历所有的书籍”,通过名字进行对比,实现找到功能,并将书籍的借出状况标为(被借出)。

小编这里通过循环遍历,从0下标的书找,将对应下标的值对应的书传到book中,通过equals来进行名字对比。若找到了就将借出状态改为true.并且在输出借阅之前判断这本书是否已经被借出,表示不能再次借阅。

实例如下:

请输入你要借的书名:
西游记
找到了你要借阅的书籍

那么此时我们可以看这本书的状态

 1
查找书籍
请输入你要查找的书
西游记
找到了你要的书
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=已被借出}

4.3.删除图书

代码如下:

public void work(Booklist booklist) {
        System.out.println("删除书籍");
        System.out.println("请输入你要删除的书籍");
        Scanner sc = new Scanner(System.in);
        String name = sc.nextLine();
        int size = booklist.getSizeBook();
        int index=-1;
        for (int i = 0; i < size ; i++) {
            Book book = booklist.getBook(i);
            if (book.getBookName().equals(name)) {
                System.out.println("找到了你要删除的书");
                index=i;
                break;
            }
        }
        if(index==-1){
            System.out.println("没有找到你要的书");
        }
        for (int j = 0; j < size - 1; j++) {
            Book book1 = booklist.getBook(index + 1);
            booklist.setBook(index, book1);
            index++;
        }
        booklist.setSizeBook(size-1);
        System.out.println("删除成功");

和上述一样,通过遍历找到要删除的书以及下标,通过下标加1将后一本书传到删除书的位置,进行覆盖,并且size表示的书的数目减一,为遍历循环条件准备。这里小编还设置了变量表示来控制提示语句的输出。

实例展示:

3
删除书籍
请输入你要删除的书籍
西游记
找到了你要删除的书
删除成功

显示图书,观察是否删除 

 4
显示书籍
Book{bookName='水浒传', author='施耐庵', price=59, types='小说', isBorrow=未被借出}
Book{bookName='三国演义', author='罗贯中', price=67, types='小说', isBorrow=未被借出}

此时发现西游记这本书已经被删除 

4.4.退出系统

代码如下:

 public void work(Booklist booklist) {
        System.out.println("退出系统");
        System.exit(0);
    }

System.exit(0)表示return 0; 

实例展示:

请输入你的操作
0
退出系统

Process finished with exit code 0

4.5. 归还书籍

代码如下:

public void work(Booklist booklist) {
        System.out.println("归还书籍");
        System.out.println("请输入你要借的书名:");
        Scanner sc=new Scanner(System.in);
        String name=sc.nextLine();
        int size= booklist.getSizeBook();
        for (int i = 0; i <size-1 ; i++) {
            Book book=booklist.getBook(i);

            if (book.getBookName().equals(name)){
                if(book.isBorrow()==false){
                    System.out.println("这本书已经被归还了");
                    break;
                }
                System.out.println("找到了你要归还的书籍");
                book.setBorrow(false);
                break;
            }
            else {
                System.out.println("没有找到你归还的书");
            }
        }

 和借阅一样,只不过将借出状态改一下就行,还是通过循环找到这本书,比较名字,在改变借出状态之前,判断这本书是否已经被归还了。若没有,则改变这本书的借出状态。

实例展示:

若已经归还:

3
归还书籍
请输入你要归还的书名:
西游记
这本书已经被归还了

若没有归还:

西游记
找到了你要的书
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=已被借出}

 归还后:

西游记
找到了你要的书
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=未被借出}

 4.6.查找书籍

代码如下:

public void work(Booklist booklist) {
        System.out.println("查找书籍");
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入你要查找的书");
        String name=sc.nextLine();
        int num=booklist.getSizeBook();
        int index=0;
        for (int j = 0; j <num ; j++) {
            Book book=booklist.getBook(j);
            if(book.getBookName().equals(name)){
                System.out.println("找到了你要的书");
                System.out.println(book);
                index=1;
                break;
            }
        }
        if(index==0){
            System.out.println("没有找到你查找的书");
        }
    }

 通过循环遍历书籍,还是通过名字比较,若一样则打印要找的书籍,并且小编这里也设置了一个变量来控制提示语句的打印。

实例展示:

1
查找书籍
请输入你要查找的书
西游记
找到了你要的书
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=未被借出}

4.7.显示书籍

代码如下:

 public void work(Booklist booklist) {
        System.out.println("显示书籍");
        int length=booklist.getSizeBook();
        for (int i = 0; i <length ; i++) {
            System.out.println( booklist.getBook(i));
        }
    }

这个就相对比较简单,通过循环遍历来显示每本书的信息。

这里的 booklist.getBook()就是Book book=booklist.getBook(i)

system.out.println(book)

实例展示:

4
显示书籍
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=未被借出}
Book{bookName='水浒传', author='施耐庵', price=59, types='小说', isBorrow=未被借出}
Book{bookName='三国演义', author='罗贯中', price=67, types='小说', isBorrow=未被借出}

 5.总结

小编认为图书管理系统,是对我们面向对象编程的一次考验,其中的向上转型多态思想是链接各个功能的重要思想,以及各个部分功能的完善也能够帮助我们对逻辑思维能力的提升。

限于小编能力有限,代码或者解释可能有误,希望各位uu提出宝贵意见。

代码已经上传gitee码云了,想看的uu自取哟Library: 图书管理系统

制作不易,给小编一个小小的赞吧。

;