Java - 图书馆管理系统

项目介绍:此项目的业务代码方面比较简单,实现的功能也比较简单,只有查找,删除,增加,借阅,归还书籍这些简单的操作。而借阅,归还等等也只是用书籍的一个boolean数据成员来保存。练习此项目的主要目的是学习巩固Java的接口,类和对象,多态,动态绑定等面向对象的知识。

大致分为几个模块:

1. book包,存储Book.java  和 BookList.java 它的作用从名字就可以看出了     

2. operation包,以一个IOperation接口为根本,将那些操作封装为类,这些类都implements那个IOperation接口。主要就是提供那些增,删,查,借阅,归还的操作。详细见下文。

3. user包,User.java  GeneralUser.java  Administrator.java 用到了继承和多态,细节见下文。

最后就是一个main.cpp 文件,作为以上三个包的对象的汇总,实现这个图书馆管理系统。

注: 此项目的实现逻辑并不一定是最好的,也不一定是合理的,旨在学习面向对象编程。

book包

Book.java

package book;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 15:38
 */
public class Book {
    private String bookName;
    private String authorName;
    private double price;
    private String type;
    private boolean isBorrowed;
    public Book(String bookName, String authorName, double price, String type) {
        this.bookName = bookName;
        this.authorName = authorName;
        this.price = price;
        this.type = type;
    }
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
    public String getBookName() {
        return bookName;
    }
    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }
    public String getAuthorName() {
        return authorName;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public double getPrice() {
        return price;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getType() {
        return type;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

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

    @Override    // 重写Object类的toString方法。
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", authorName='" + authorName + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ", isBorrowed:" + (isBorrowed ?"Yes":"No") +
                '}';
    }
}

一个Java文件,建议只写一个类。这个Book类存储了书籍的基本信息,以及构造函数。剩余的就是对于每个数据成员的setter和getter方法。以及为了方便打印Book类对象信息而重写Object类的toString方法。其中的getter和setter方法,是为了实现后面在BookList类的功能而准备的接口,将数据成员封装起来,对外使用接口对这些数据成员进行操作。只有几个是后面用到的。当然,如果你后面想要扩展这个管理系统的功能,剩余的方法也会用到。

BookList.java

package book;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 15:53
 */
public class BookList {
    private Book[] books;
    private int numOfBook;

    public BookList() {
        books = new Book[10];
        books[0] = new Book("三国演义","施耐庵",18,"小说");
        books[1] = new Book("水浒传", "罗贯中", 26.6, "小说");
        books[2] = new Book("西游记", "吴承恩", 38, "小说");
        numOfBook = 3;
    }

    public int getNumOfBook() {
        return numOfBook;
    }

    public void setNumOfBook(int numOfBook) {
        this.numOfBook = numOfBook;
    }
    public Book getBook(int index) {
        return books[index];
    }
    // 其实这里完全可以写成addBook,但是因为这个功能实现成了一个类,所以这里做一些更基本的操作。
    public void setBook(int index, Book book) {
        books[index] = book;
    }
}

这里的书单存储Book类对象的方式是使用顺序表-Java的数组,这种数组不像C++的vector可以扩容,功能比较单一。所以添加了一个numOfBook数据成员存储书籍个数。 默认构造函数用于对数组初始化,后面的方法是接口,作为了 后面的增删查改操作的接口,用于对这个书籍数组进行处理。

operation包

为了学习接口,以及重写方法,当然也为了后面实现的方便。这里将每个操作封装成了类,这些类都implements一个IOperation接口,这样,我们就可以将这些操作的对象放在同一个数组中了。当然这里说也不直观,需要和后面的User类结合起来看这个的功能。

IOperation接口

public interface IOperation {
    public static final Scanner scanner = new Scanner(System.in);
    public abstract void work(BookList bookList);
}

AddOperation.java  实现增加书籍的功能,这是一个类,成员函数work实现对应的业务。

package operation;

import book.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 16:07
 */
public class AddOperation implements IOperation{
    public void work(BookList bookList) {
        System.out.println("添加图书");
        System.out.println("请输入书名: ");
        String bookName = scanner.nextLine();
        System.out.println("请输入作者: ");
        String authorName = scanner.nextLine();
        System.out.println("请输入价格: ");
        double price = scanner.nextDouble();
        System.out.println("请输入类型: ");
        String type = scanner.nextLine();
        Book book = new Book(bookName, authorName, price, type);
        int index = bookList.getNumOfBook();
        bookList.setBook(index, book);
        bookList.setNumOfBook(index + 1);
    }
}

BorrowOperation 借阅书籍 -   同样是一个类,implements 接口IOperation

public class BorrowOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅书籍");
        System.out.println("请输入要借阅书籍的名字: ");
        String bookName = scanner.nextLine();
        for(int i = 0; i < bookList.getNumOfBook(); ++i) {
            if(bookList.getBook(i).getBookName().equals(bookName)) {
                if(bookList.getBook(i).isBorrowed()) {
                    System.out.println("此书籍已被借阅");
                    System.out.println(bookList.getBook(i));
                    return;
                } else{
                    bookList.getBook(i).setBorrowed(true);
                    System.out.println("借阅成功");
                    System.out.println(bookList.getBook(i));
                    return;
                }
            }
        }
        System.out.println("此书籍不存在");
    }
}

DelOperation  删除书籍 - 同样是一个类,implements 接口IOperation

package operation;

import book.BookList;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 16:07
 */
public class DelOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("删除书籍");
        System.out.println("请输入你要删除的图书的名字");
        String name = scanner.nextLine();
        for(int i = 0; i < bookList.getNumOfBook(); ++i) {
            if(bookList.getBook(i).getBookName().equals(name)) {
                for(int j = i; j < bookList.getNumOfBook()-1; ++j) {
                    bookList.setBook(j, bookList.getBook(j+1));
                }
                bookList.setBook(bookList.getNumOfBook()-1,null);
                bookList.setNumOfBook(bookList.getNumOfBook()-1);
                System.out.println("删除成功");
                return;
            }
        }
        System.out.println("查无此书");
    }
}

DisplayOperation 打印书籍 - 同样是一个类,implements 接口IOperation

package operation;

import book.BookList;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 16:08
 */
public class DisplayOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("打印书籍");
        for(int i = 0; i < bookList.getNumOfBook(); ++i) {
            System.out.println(bookList.getBook(i));
        }
    }
}

ExitOperation 退出系统 - 同样是一个类,implements 接口IOperation

package operation;

import book.BookList;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 16:08
 */
public class ExitOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统");
        System.exit(0);
    }
}

FindOperation 查找书籍 - 同样是一个类,implements 接口IOperation

package operation;

import book.Book;
import book.BookList;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 16:08
 */
public class FindOperation implements IOperation {
    public void work(BookList bookList) {
        System.out.println("查找书籍");
        System.out.println("请输入要查找图书的书名:");
        String name = scanner.nextLine();
        for(int i = 0; i < bookList.getNumOfBook(); ++i) {
            if(bookList.getBook(i).getBookName().equals(name)) {
                System.out.println(bookList.getBook(i));
                return;
            }
        }
        System.out.println("查无此书");
        return;
    }
}

ReturnOperation 返还书籍 - 同样是一个类,implements 接口IOperation

package operation;

import book.BookList;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 16:08
 */
public class ReturnOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("返回书籍");
        System.out.println("请输入要归还书籍的名字: ");
        String bookName = scanner.nextLine();
        for(int i = 0; i < bookList.getNumOfBook(); ++i) {
            if(bookList.getBook(i).getBookName().equals(bookName)) {
                bookList.getBook(i).setBorrowed(false);
                System.out.println("归还成功");
                System.out.println(bookList.getBook(i));
                return;
            }
        }
        System.out.println("此书籍不存在");
    }
}

整体而言,这里运用了实现接口的知识。其实这些功能都可以实现到那个BookList的类内,作为BookList的成员函数,更方便的对Book[] 操作。不过,这只是不同的实现思路罢了。并且如果实现到一个类的成员函数,那么后面main函数处就需要用switch case语句对用户选择的书籍,调用对应的方法,这也是不方便的。

User包

因为 普通用户和管理员都有一些公有的属性或方法,所以创建一个User类 作为基类/父类,由普通用户类和管理员类继承User类。

User.java

package user;

import book.BookList;
import operation.IOperation;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yangzilong
 * Date: 2022-07-03
 * Time: 15:58
 */
public abstract class User {
    private String userName;
    protected IOperation[] operations;  // 基类对象引用的数组

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

    protected String getUserName() {
        return userName;
    }

    public abstract int menu();
    public void doWork(int input, BookList bookList) {
        operations[input].work(bookList);
    }
}

GeneralUser.java 普通用户类 继承 User

public class GeneralUser extends User {
    public GeneralUser(String userName) {
        super(userName);
        super.operations = new IOperation[] {
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }
    public int menu() {
        System.out.println("======hello "+ super.getUserName() + " welcome=====");
        System.out.println("1.查找图书");
        System.out.println("2.借阅图书");
        System.out.println("3.归还图书");
        System.out.println("0.退出系统");
        System.out.print("请输入你的操作:>");
        Scanner scanner = new Scanner(System.in);
        return scanner.nextInt();
    }
}

Administrator.java  管理员类 继承 User

public class Administrator extends User {
    public Administrator(String name) {
        super(name);
        super.operations = new IOperation[] {
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DelOperation(),
                new DisplayOperation()
        };
    }
    public int menu(){
        System.out.println("======hello "+ super.getUserName() + " welcome=====");
        System.out.println("1.查找图书");
        System.out.println("2.增加图书");
        System.out.println("3.删除图书");
        System.out.println("4.打印图书");
        System.out.println("0.退出系统");
        System.out.print("请输入你的操作:>");
        Scanner scanner = new Scanner(System.in);
        return scanner.nextInt();
    }
}

这里就和operation包结合起来了,可以看到User有一个IOperation对象引用的数组,而operation包中的其他类都implements这个接口。这里的数组就可以存储普通用户类或者管理员类的操作。

而User类有一个抽象方法menu,Administrator和GeneralUser都重写了这个menu。具体怎么用还需要看主函数,不过毋庸置疑的是,这里肯定用到了动态绑定和多态。

Main.java

public class Main {
    public static User login() {
        System.out.println("请输入你的姓名: ");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("请输入你的身份:1 - 管理员  2 - 普通用户");
        while(true) {
            int choice = scanner.nextInt();
            if (choice == 1) {
                return new Administrator(name);
            } else if (choice == 2) {
                return new GeneralUser(name);
            } else {
                System.out.println("输入错误,请重新输入");
            }
        }
    }
    public static void main(String[] args) {
        BookList bookList = new BookList();
        User user = login();   // 基类引用引用派生类对象。
        while (true) {
            int n = user.menu();  // 动态绑定,运行时绑定,多态,运行时多态。
//            user.operations[n].work(bookList);  // 这里的操作迫使user把operations数据成员更改为public的。
            // 但是,user的operations设为protected更为合适。
            user.doWork(n, bookList);
        }
    }
}

不看这个,是很难理解上方那些包的作用的。

首先肯定让你输入数字选择身份,同时需要输入名字。因为上方把不同身份实现了对应的类,所以login函数中new不同的对象,因为这些对象都继承自User,所以返回值为User是合法的。

GeneralUser 和 Administrator的mune方法进行了重写,调用时发生了动态绑定,即多态。menu方法内需要用户选择操作,以int类型返回回去。再根据User类的doWork方法,调用对应的数组中的类的work方法,对传入的bookList进行处理。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值