在前面几篇博客中,我陆续讲解了java的三大特性封装,继承和多态,这次的简单图书管理项目主要是为了练习继承,接口和多态的使用,那么就用这篇博客来讲解一下这个小项目,目的只是为了练习。

我们先来分析一下,首先进入图书管理系统,要求使用者首先输入自己的名字,输入完成后选择进入系统的身份,有管理员和普通用户两种身份,要求i管理员有增添图书,删除图书,查找图书,展示图书和退出系统五种功能;而作为普通用户则要求有查找图书,借阅图书,归还图书和退出系统四种功能。

一,BOOK包

Book类

我们发现不论是管理员还是普通用户,他们除了退出系统之外的功能都是对书进行操作;所以我们首先创建一个Book类,Book应该具有String类型的书名(name),String类型的作者(author),int类型的价钱(price),String类型的书的类型(type)和Boolean类型的借阅状态(isBorrow)五种成员变量,一个标准的类应该至少具有一个无参的构造方法和一个全参的构造方法,正好Boolean类型的变量默认值为false,构造方法是创建类的时候使用的,我们在管理员的增添图书的功能中正好要新建一个Book类因为新书一定是未借阅的,届时就不必录入是否借阅的信息,从而默认就是未借阅的状态。其次我们在普通用户层面有借阅图书和归还图书两种功能,在借阅图书时如果此书已被借出则无法再借出,否则则可以将此书借出,之后将它的借阅状态置为true(已借出)而在归还图书时需要首先判断该图书是否被借出,如果被借出才能被归还,再将该书的借阅状态置为false(未借出),所以我们需要获取书的借阅状态(getisBroow())和改变书的借阅状态(setisBrrow());在普通用户和管理员层面都有的查找图书功能中,我们需要用户输入要查找的书的名字来在已有的书中来寻找,方式就是通过String类的equals方法来在已有的书中进行名字的匹配,在此过程中我们需要获取书的名字(getname()),找到之后我们便需要向用户来展示一下该书的各种信息,所以我们在Book类中需要重写toString方法,需要注意的时要根据书的isBrrow的状态来打印已借出(true)或者未借出(false)。

总结一下:

Book类应该有以下属性:

1.String name;
2.String author;
3.int price;
4.Sring type;
5.Boolean isBrrow;
6.空参构造方法;
7.全参构造方法;
8.toString方法;
9.getname,getIsBrrow,setisBrrow方法

接下来我们给出Book类的代码:

package BOOK;

 public class Book {
    String name;
    String author;
    int price;
    String type;
    boolean isBorrow;
    public Book() {

    }

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

    @Override
    public String toString() {
        if(isBorrow)
        {
             return "{" +
                "书名:'" + name + '\'' +
                ", 作者:'" + author + '\'' +
                ", 价格:" + price +
                ", 类型:" + type + '\'' + " 已借出" +
                '}';
        }else{
            return "{" +
                    "书名:" + name + '\'' +
                    ", 作者:" + author + '\'' +
                    ", 价格:" + price +
                    ", 类型:" + type + '\'' + " 未借出" +
                    '}';
        }

    }

     public String getName() {
         return name;
     }

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

     public boolean isBorrow() {
         return isBorrow;
     }
 }

Booklist类

Book类的每个实例化对象都是一本书,而在进行增删查操作时往往需要对Book类的每个对象进行操作,为了方便操作我们将Book类的对象保存在Booklist类的Book类型的books数组中,在打开系统的时候先让它有几本书存在,我们使用实例代码块来创建几个Book类的对象并且存放在books数组中,为了方便管理,我们需要设置一个书的数量的成员变量并且仅对本类可见,所以我们是使用private关键字对其进行修饰,并且为其设置get和set方法

总结一下:

Booklist类 应该具有以下属性:

1.保存Book类对象的数组books;

2.仅对本类可见的booknum及其get和set方法;

3.增添初始图书的实例代码块;

接下来我们给出Booklist类的代码:

package BOOK;

import java.util.Arrays;

public class Booklist {
    public Book [] books = new Book[10];
    private int booknum;
    {
        books[0] = new Book("java","张三",12,"编程",false);
        books[1] = new Book("pathon","lisi",12,"编程",false);
        books[2] = new Book("matlab","wangwu",12,"编程",false);
        booknum = 3;
    }
    public int getBooknum() {
        return booknum;
    }

    public void setBooknum(int booknum) {
        this.booknum = booknum;
    }
}

二,FUNCTION包

1.Ifunction接口

Ifunction接口是所有功能类的公共规范,所以它应该具有抽象 方法work,而且这个方法的操作对象应该是Boolist类的对象

接下来我们给出Ifunction接口的代码:

package FUNCTION;

import BOOK.Booklist;

public interface Ifunction {
    void work(Booklist booklist);
}

2.Ifunction接口的实现类们

为了方便以后我们对各个实现类的work方法的调用,所以这些实现类都应该实现Ifunction接口,并且对其中的work方法进行重写,由于大多是逻辑代码,所以我们不再赘述,直接给出代码

1.AddBook

package FUNCTION;

import BOOK.Book;
import BOOK.Booklist;

import java.util.Scanner;

public class AddBook implements Ifunction{
    @Override
    public void work(Booklist booklist) {
        System.out.println("请输入图书名字:");
        String name = new Scanner(System.in).next();
        System.out.println("请输入图书作者!");
        String author = new Scanner(System.in).next();
        System.out.println("请输入图书价格");
        int price = new Scanner(System.in).nextInt();
        System.out.println("请输入 图书类型");
        String type = new Scanner(System.in).next();
        booklist.books[booklist.getBooknum()] = new Book(name,author,price,type,false);
        booklist.setBooknum(booklist.getBooknum()+1);
    }
}

2.Borrow类

package FUNCTION;

import BOOK.Booklist;

import java.util.Scanner;

public class Borrow implements Ifunction{
    @Override
    public void work(Booklist booklist) {
            System.out.println("请输入书的名字");
            String name = new Scanner(System.in).next();
            for (int i = 0; i < booklist.getBooknum(); i++) {
                if (name.equals(booklist.books[i].getName()))
                {
                    if (!booklist.books[i].isBorrow()){
                        booklist.books[i].setBorrow(true);
                        System.out.println("借阅成功");
                    }else {
                        System.out.println("该书已借出");
                    }
                    return;
                }
            }
            System.out.println("暂无此书!");
        }
    }

3.Delete

package FUNCTION;

import BOOK.Booklist;

import java.util.Scanner;

public class Delete implements Ifunction{
    @Override
    public void work(Booklist booklist) {
        System.out.println("请输入删除书的名字");
        String name = new Scanner(System.in).next();
        for (int i = 0; i < booklist.getBooknum(); i++) {
            if (name.equals(booklist.books[i].getName()))
            {
                for (int j = 0; j < booklist.getBooknum()-i-1; j++) {
                    booklist.books[i+j] = booklist.books[i+j+1];
                }
                booklist.setBooknum(booklist.getBooknum()-1);
                System.out.println("删除成功!");
                return;
            }
        }
        System.out.println("暂无此书");
    }
}

4.Display

package FUNCTION;

import BOOK.Booklist;

public class Display implements Ifunction{
    @Override
    public void work(Booklist booklist) {
        for (int i = 0; i < booklist.getBooknum(); i++) {
            System.out.println(booklist.books[i].toString());
        }
    }
}

5.Exit

package FUNCTION;

import BOOK.Booklist;

public class Exit implements Ifunction{
    @Override
    public void work(Booklist booklist) {
        System.exit(0);
    }
}

6.Return

package FUNCTION;

import BOOK.Booklist;

import java.util.Scanner;

public class Return implements Ifunction{
    @Override
    public void work(Booklist booklist) {
        System.out.println("请输入书的名字");
        String name = new Scanner(System.in).next();
        for (int i = 0; i < booklist.getBooknum(); i++) {
            if (name.equals(booklist.books[i].getName()))
            {
                if (booklist.books[i].isBorrow()){
                    booklist.books[i].setBorrow(false);
                    System.out.println("归还成功");
                }else {
                    System.out.println("该书未借出");
                }
                return;
            }
        }
        System.out.println("暂无此书!");
    }
    }

7.Search

import BOOK.Booklist;

import java.util.Scanner;

public class Search implements Ifunction{
    @Override
    public void work(Booklist booklist) {
        System.out.println("请输入书的名字");
        String name = new Scanner(System.in).next();
        for (int i = 0; i < booklist.getBooknum(); i++) {
            if (name.equals(booklist.books[i].getName()))
            {
                System.out.println(booklist.books[i].toString());
                return;
            }
        }
        System.out.println("暂无此书!");
    }
}

三,USER包

1.抽象类User

对于普通用户和管理员层面我们都有使用者的名字,并且都有各自的功能选择界面以及根据用户的选择进行相应的工作的方法,所以:

User类应该具有以下属性:

1.String类型的name;

2.保存功能类的Ifunction类型的数组;

3.抽象方法main方法;

4.根据用户选择对booklist对象进行操作的dofunction方法;

接下来我们给出代码:

package USER;

import BOOK.Booklist;
import FUNCTION.Ifunction;

public abstract class User {
    String name;
    Ifunction ifunction[];
    public abstract int main() ;
    public User(String name) {
        this.name = name;
    }
    public void dofunction(int i,Booklist booklist){
        ifunction[i].work(booklist);
    }
}

2.普通用户PublicUser和管理员Administrator类

此类继承User类,需要根据对应的功能重写main方法,并在构造方法中对其Ifunction数组做出赋值选择其需要实现的功能,代码如下:

package USER;

import BOOK.Booklist;
import FUNCTION.*;

import java.util.Scanner;

public class PublicUser extends User {
    public PublicUser(String name) {
        super(name);
        System.out.println("欢迎" + name);
        ifunction = new Ifunction[]{
                new Exit(),
                new Borrow(),
                new Return(),
                new Search()
        };

    }
    @Override
    public int main() {
        System.out.println("0.Exit 1.Boorow 2.Rerurn 3.Search ");
        System.out.println("请输入你的选择!");
        int i = new Scanner(System.in).nextInt();
        while (true){
            if(i >= 0 && i<4){
                return i;
            }else{
                System.out.println("输入有误,重新输入!");
                i = new Scanner(System.in).nextInt();
            }
        }
    }
}

管理员层面与普通用户层面同理,只是需要实现的功能不同,我们直接给出代码:

package USER;

import BOOK.Booklist;
import FUNCTION.*;

import java.util.Scanner;

public class Administrator extends User  {
    public Administrator(String name) {
        super(name);
        System.out.println("欢迎" + name);
        ifunction = new Ifunction[]{
                new Exit(),
                new AddBook(),
                new Delete(),
                new Search(),
                new Display()
        };
    }
    @Override
    public int main() {
        System.out.println("0.Exit 1.Addbook 2.Deletebook 3.Search 4.Display");
        System.out.println("请输入你的选择!");
        int i = new Scanner(System.in).nextInt();
        while (true){
            if(i >= 0 && i<5){
                return i;
            }else{
                System.out.println("输入有误,重新输入!");
                i = new Scanner(System.in).nextInt();
            }
        }
    }
}

3.有main方法的程序的入口Main类

该系统是对booklist对象进行操作,所以在程序开始的时候我们首先需要创建一个booklist对象,然后进入用户输入姓名选择身份界面,我们将这一步写成一个Main类的静态方法而且需要根据用户的不同选择来返回PublicUser类的对象或者Administrator类的对象,所以我们需要用其父类的对象进行接收,这是一种多态的写法,方便我们后续对其dofunction方法进行调用来选择对应的操作

代码如下:

package USER;

import BOOK.Booklist;
import FUNCTION.Ifunction;

import java.util.Scanner;

public class Main {
    public static User login(){
        System.out.println("请输入你的名字:");
        String name = new Scanner(System.in).next();
        System.out.println("选择你的身份:1.普通用户 2.管理员");
        int i = new Scanner(System.in).nextInt();
        while(true){
            switch (i){
                case 1 :
                    return new PublicUser(name);
                case 2 :
                    return new Administrator(name);
                default:
                    System.out.println("输入错误请重新输入:");
                    i =  new Scanner(System.in).nextInt();;
            }
        }

    }
    public static void main(String[] args) {
        Booklist booklist = new Booklist();
        User user = login();
        while (true){
            user.dofunction(user.main(),booklist);
        }
    }
}

至此,简单的图书管理系统项目完成,代码也均已给出。