Java模拟实现图书管理系统

一、book包

抽象出与书有关的类,创建一个book包,将这些类写入book包下。

1.1Book类

定义Book类的各种属性,这里对这些属性进行了封装,注意borrow属性的初始值是false,构造方法对除borrow属性之外的属性进行赋值,构造方法有参数,然后重写Object类的toString方法(改了borrow的输出)。

package book;
public class Book {
    
    
    private String name;
    private String autor;
    private int price;
    private String type;
    private boolean borrow;
    public String getName() {
    
    
        return name;
    }
    public void setName(String name) {
    
    
        this.name = name;
    }
    public String getAutor() {
    
    
        return autor;
    }
    public void setAutor(String autor) {
    
    
        this.autor = autor;
    }
    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 getBorrow() {
    
    
        return borrow;
    }
    public void setBorrow(Boolean borrow) {
    
    
        this.borrow = borrow;
    }
    public Book (String name, String autor, int price, String type){
    
    
        this.name = name;
        this.autor = autor;
        this.price = price;
        this.type = type;
    }
    @Override
    public String toString() {
    
    
        return "Book{" +
                "name='" + name + '\'' +
                ", autor='" + autor + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ((borrow == true) ? "已被借出":"未被借出") +
                '}';
    }
}

1.2BookList类

属性有Book类型的数组(这里数组大小为10),书的数量,对这些属性进行封装。在构造方法中用new关键字创建三个对象,将这三个对象赋值给Book类型的数组的前三个元素,将书的数量赋值为三,构造方法无参。

package book;
public class BookList {
    
    
    private Book[] bookList = new Book[10];
    private int booknumbers;
    public Book getBook(int pos) {
    
    
        return bookList[pos];
    }
    public void setBook(int pos, Book book) {
    
    
        bookList[pos] = book;
    }
    public int getBooknumbers() {
    
    
        return booknumbers;
    }
    public void setBooknumbers(int booknumbers) {
    
    
        this.booknumbers = booknumbers;
    }
    public BookList(){
    
    
        this.bookList[0] = new Book("西游记", "吴承恩", 100, "小说");
        this.bookList[1] = new Book("红楼梦", "曹雪芹", 100, "小说");
        this.bookList[2] = new Book("爆笑校园", "朱斌", 20, "漫画");
        this.booknumbers = 3;
    }
}

二、user包

抽象出与使用者有关的类,将这些类放入创建的user包中。

2.1User类

User类的属性有使用者名字,操作接口类型的数组(用于存放各种操作)。有参的构造方法对使用者名字进行赋值。然后写抽象的菜单方法,继承User类的子类要重写抽象菜单方法。最后写操作方法doOperate,在这个方法中,用操作接口类型数组对应下标的元素调用其重写的接口中的work方法,work方法是实现操作接口的操作类中已经重写的操作接口中的方法,操作接口类型数组对应的下标由操作者来选择。

package user;
import book.BookList;
import operate.IOperation;
public abstract class User {
    
    
    protected String name;
    public IOperation[] iOperation;
    public User(String name){
    
    
        this.name = name;
    }
    public abstract int menu();
    public void doOperate(int choice, BookList bookList){
    
    
        iOperation[choice].work(bookList);
    }
}

2.2AdminUser类

AdminUser类继承User类,在这个类的构造方法中先用super()对父类的使用者名字属性进行构造,再初始化操作接口类型的数组,构造方法有参,以后选好身份之后,各种操作(数组元素)就会被创建好,数组元素的类型是实现了操作接口的各种操作类类型,而创建数组对象时数组是操作接口类型,这里是向上转型。然后重写菜单方法,菜单方法的返回值是整型类型,用于体现操作者的选择。

package user;
import operate.*;
import java.util.Scanner;
public class AdminUser extends User{
    
    
    public AdminUser(String name) {
    
    
        super(name);
        this.iOperation = new IOperation[]{
    
    //选好身份之后,各种操作就会被new好
                new ExitOperate(),
                new FindOperate(),
                new AddOperate(),
                new DelOperate(),
                new ShowOperate()
        };
    }
    @Override
    public int menu() {
    
    
        System.out.println(this.name + " 欢迎来到管理员用户菜单");
        System.out.println("1.查找图书");
        System.out.println("2.新增图书");
        System.out.println("3.删除图书");
        System.out.println("4.显示图书");
        System.out.println("0.退出系统");
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
}

2.3NormalUser类

NormalUser类和AdminUser类类似,也是继承于User类。与AdminUser类不同的是,NormalUser类的构造方法初始化操作接口类型的数组时创建的各种操作类对象不同,重写的菜单方法里面的各种选择也不同。

package user;
import operate.*;
import java.util.Scanner;
public class NormalUser extends User{
    
    
    public NormalUser(String name) {
    
    
        super(name);
        this.iOperation = new IOperation[]{
    
    //选好身份之后,各种操作就会被new好
                new ExitOperate(),
                new FindOperate(),
                new BorrowOperate(),
                new ReturnOperate(),
        };
    }
    @Override
    public int menu() {
    
    
        System.out.println(this.name + " 欢迎来到普通用户菜单");
        System.out.println("1.查找图书");
        System.out.println("2.借阅图书");
        System.out.println("3.归还图书");
        System.out.println("0.退出系统");
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
}

三、实现运行逻辑的Main_类

首先创建BookList类型的对象,此时书架中的三本书已经加载好,再在while循环中调用登录方法,登录方法的返回值类型为User,在登录方法中,如果操作者选择管理员,则创建一个管理员类型(AdminUser类型)的对象,如果选择读者,则创建一个普通用户类型(NormalUser类型)的对象,这时会调用相应类的构造方法,User类中操作接口类型的数组就会被初始化,各种操作类的对象也会被创建好,数组元素被初始化为相应类型用户的各种操作类的对象。将创建好的管理员类型或普通用户类型的对象作为登录方法的返回值赋值给User类型的变量user,这里发生了向上转型,用user调用菜单方法,这里发生了动态绑定,因为AdminUser类和NormalUser类重写了User类的构造方法,然后将结果赋值给整型变量choice,用user调用操作方法doOperate,doOperate通过user和choice确定调用哪种类型用户的哪个操作方法,user是哪种类型用户,User类中接口类型的数组元素就会被初始化哪种类型用户的操作类对象,通过choice就可以确定调用哪种类型用户的哪个操作方法。

import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
public class Main_ {
    
    
    public User login(){
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入用户名:");
        String name = scanner.nextLine();
        System.out.println("请选择身份:0-->管理员 1-->读者");
        int chose = scanner.nextInt();
        if(chose == 0){
    
    
            return new AdminUser(name);
        }else {
    
    
            return new NormalUser(name);
        }
    }
    public static void main(String[] args) {
    
    
        BookList bookList = new BookList();
        Main_ main = new Main_();
        while (true){
    
    
            User user = main.login();//向上转型
            int choice = user.menu();//动态绑定
            user.doOperate(choice, bookList);
        }
    }
}

四、operate包

将各种操作抽象出一个类,用接口对这些类的功能进行规范起来,这时这些操作类只要实现这个接口就可以了,将这个操作接口和这些操作类写入创建的operate包中。

4.1IOperation接口

写了一个返回值类型为空,参数为BookList类型的变量(BookList bookList)的work方法,因为各种操作均需用到书架类中的内容,所以用BookList bookList作为参数,这个方法是抽象方法,实现这个接口的操作类要重写这个方法。

package operate;
import book.BookList;
public interface IOperation {
    
    
    void work(BookList bookList);
}

4.2AddOperate类

AddOperate类实现IOperation接口,重写了IOperation接口中的work方法。在重写的work方法中,输入要增加书的书名、作者、价格、类型。创建一个Book类型的对象,将要增加书的书名、作者、价格、类型作为参数放入新创建的Book类型对象的构造方法中,将这个对象放入以当前书数目为下标的书数组内容当中(因为书数组下标从0开始),然后当前书数目+1。

package operate;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class AddOperate implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
            Scanner scanner = new Scanner(System.in);
            System.out.println("输入要增加的书的书名");
            String name = scanner.nextLine();
            System.out.println("输入要增加的书的作者");
            String autor = scanner.nextLine();
            System.out.println("输入要增加的书的价格");
            int price = scanner.nextInt();
            scanner.nextLine();
            System.out.println("输入要增加的书的类型");
            String type = scanner.nextLine();
            int currentNums = bookList.getBooknumbers();
            Book book = new Book(name, autor, price, type);
            bookList.setBook(currentNums, book);
            bookList.setBooknumbers(currentNums + 1);
            System.out.println("新增图书成功");
    }
}

4.3BorrowOperate类

输入要借阅书的名字,遍历书架,如果找到了这本书,书的borrow属性为true,则书已被借走,否则将书的borrow属性改为true,借阅成功。如果找不到这本书,则书不存在。

package operate;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowOperate implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        System.out.println("请输入你要借阅的图书的名字");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();
        int currentNums = bookList.getBooknumbers();
        for (int i = 0; i < currentNums; i++) {
    
    
            if(bookList.getBook(i).getName().equals(bookName)) {
    
    
                if((bookList.getBook(i).getBorrow()) != true) {
    
    
                    bookList.getBook(i).setBorrow(true);
                    System.out.println("借阅图书成功");
                }else {
    
    
                    System.out.println("这本书已被借走");
                }
                return;
            }
        }
        System.out.println("没有你要借阅的图书");
    }
}

4.4DelOperate类

DelOperate类实现IOperation接口,重写了IOperation接口的word方法,输入要删除书的书名,遍历书架(书数组),如果找到了要删除的书,则记录这本书的下标i,即将这本书的下标i赋值给整型变量ret,然后从书数组下标为ret的书开始,i++为下标的书赋给i为下标的书,为了防止书数组越界,这个操作执行的次数是当前书数目-1次。如果找不到这本要删除的书,则要删除的书不存在。

package operate;
import book.BookList;
import java.util.Scanner;
public class DelOperate implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        System.out.println("请输入你要删除的图书的名字");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();
        int currentNums = bookList.getBooknumbers();
        int target = -1;
        for (int i = 0; i < currentNums; i++) {
    
    
            if(bookList.getBook(i).getName().equals(bookName)) {
    
    
                target = i;
                break;
            }
        }
        if(target == -1) {
    
    
            System.out.println("没有你要删除的书");
        }
        for (int i = target; i < currentNums - 1; i++) {
    
    
            bookList.setBook(i, bookList.getBook(i + 1));
        }
        bookList.setBooknumbers(currentNums - 1);
        System.out.println("删除图书成功");
    }
}

4.5ExitOperate类

ExitOperate类实现IOperation接口,重写了IOperation接口的word方法,用System.exit(0);退出程序,在退出程序前将书架上的书(书数组中的内容)置为null,当前书的数量置为0。

package operate;
import book.BookList;
public class ExitOperate implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        int currentNums = bookList.getBooknumbers();
        for (int i = 0; i < currentNums; i++) {
    
    
            bookList.setBook(i, null);
        }
        bookList.setBooknumbers(0);
        System.out.println("退出系统成功");
        System.exit(0);
    }
}

4.6FindOperate类

FindOperate类实现IOperation接口,重写了IOperation接口的word方法,输入要查找书的书名,遍历书数组,找到则将书打印出来,找不到则没有要查找的书。

package operate;
import book.BookList;
import java.util.Scanner;
public class FindOperate implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        System.out.println("请输入你要查找的图书的名字");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();
        int currentNums = bookList.getBooknumbers();
        for (int i = 0; i < currentNums; i++) {
    
    
            if(bookList.getBook(i).getName().equals(bookName)) {
    
    
                System.out.println(bookList.getBook(i));
                return;
            }
        }
        System.out.println("没有你要查找的图书");
    }
}

4.7ReturnOperate类

ReturnOperate类实现IOperation接口,重写了IOperation接口的word方法,输入要归还书的书名,遍历书数组,找到了要归还的书,若书的borrow属性是true,则将书的borrow属性改为false,归还成功,若书的borrow属性是false,则书已经存在不用归还。找不到要归还的书,则要归还的书不属于图书馆,不用归还。

package operate;
import book.BookList;
import java.util.Scanner;
public class ReturnOperate implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        System.out.println("请输入你要归还的图书的名字");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();
        int currentNums = bookList.getBooknumbers();
        for (int i = 0; i < currentNums; i++) {
    
    
            if(bookList.getBook(i).getName().equals(bookName)) {
    
    
                if((bookList.getBook(i).getBorrow()) == false) {
    
    
                    System.out.println("图书存在,不用归还");
                }else {
    
    
                    bookList.getBook(i).setBorrow(false);
                }
                return;
            }
        }
        System.out.println("该图书不属于图书馆,不用归还");
    }
}

4.8ShowOperate类

ShowOperate类实现IOperation接口,重写了IOperation接口的word方法,遍历书数组,将每本书打印出来。

package operate;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class ShowOperate implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        int currentNums = bookList.getBooknumbers();
        for (int i = 0; i < currentNums; i++) {
    
    
            Book book = bookList.getBook(i);
            System.out.println(book);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/zhanlongsiqu/article/details/130652061