JavaSE|【Java】图书管理系统(菜鸟版)


文章目录

    • 前言
    • 一、对象与功能剖析
    • 二、代码实现
      • 2.1 Book包
        • 2.1.1 书籍类(Book)
        • 2.1.2 书架类(BookList)
      • 2.2 Users 包
        • 2.2.1 用户类(User)
        • 2.2.2 普通用户类(NormalUser)
        • 2.2.3 图书管理员类(Administrator)
      • 2.3 Function 包
        • 2.3.1 IFunction 接口
        • 2.3.2 查找书籍(FindFunction)
        • 2.3.3 增加书籍 (AddFunction)
        • 2.3.4 删除书籍(DelFunction)
        • 2.3.5 打印书籍(DisplayFunction)
        • 2.3.6 整理书籍(SortFunction)
        • 2.3.7 借阅书籍(BorrowFunction)
        • 2.3.8 归还书籍(ReturnFunction)
        • 2.3.9 退出系统(ExitFUnction)
      • 2.4 Main类
    • 三、项目总结

前言 在前面的几节博客中,山居向大家剖析了类和对象,介绍了包,详析了面向对象的基本特征,生动讲解了什么是接口,总结的过程中,收益匪浅。
此次,山居将容这些东西于一体,写一个 Java 图书管理系统
JavaSE|【Java】图书管理系统(菜鸟版)
文章图片

通通都没有!(不是)。。。
该图书馆管理系统只是为了总结之前所学,将其投入应用当中,不整太高级的,只为融会贯通,菜鸟版图书管理系统,菜鸟值得拥有!
JavaSE|【Java】图书管理系统(菜鸟版)
文章图片

一、对象与功能剖析 面向对象编程首先需要明白对象都有哪些
建立一个图书管理图书系统应该有的大体对象有:图书用户以及管理系统的各种功能
关于图书
需要一个类(Book)包含图书的各项信息
需要一个书架,将书(Book)放在其中
关于用户
普通用户
图书管理员
关于功能(对于不同的用户实现的功能有所不同)
普通用户:
  • 查找书籍
  • 借阅书籍
  • 归还书籍
  • 退出系统
图书管理员:
  • 查找书籍
  • 增加书籍
  • 删除书籍
  • 打印书籍
  • 整理书籍
  • 退出系统
所有的功能都是针对 BookList 类展开的,为了将各种方法联系在一起,需要功能们都实现接口 IFunction,重写该接口中的抽象方法。
最后还需要一个 Main 类将上面的类、各种信息串通在一起
JavaSE|【Java】图书管理系统(菜鸟版)
文章图片

二、代码实现 此次的项目一共建立了三个包来装类
  • Book 包:装图书相关类
  • Users 包:装用户类
  • Function 包:装功能类
2.1 Book包
2.1.1 书籍类(Book)
  • 书籍信息包括书名作者价格以及是否被借出(为了安全性,实现封装,书籍信息用 private 关键字修饰)
  • 提供书籍信息的 Getter and Setter 方法(alt + insert -> Getter and Setter),使外界可以获取书的信息
  • 提供书籍类含有书名、作者、价格的三个参数的构造方法(借出状态是一种状态,无需传参)
  • 重写 toString 方法(alt + insert -> toString()),可以做适当的修改,例如借出状态默认为 false(打印未借出),当书被借出,其状态为 true (打印已借出)
package Book; public class Book {//书籍相关信息 private String name; private String author; private Double price; private Boolean isBorrow = false ; //书籍信息的 Getter and Setter 方法 public String getName() {return name; } public void setName(String name) {this.name = name; } public String getAuthor() {return author; } public void setAuthor(String author) {this.author = author; } public Double getPrice() {return price; } public void setPrice(Double price) {this.price = price; } public Boolean getBorrow() {return isBorrow; } public void setBorrow(Boolean borrow) {isBorrow = borrow; } public Book(String name, String author, Double price) {this.name = name; this.author = author; this.price = price; } //重写 toString 方法 @Override public String toString() {return "Book{" + "name='" + name + '\'' + ", author='" + author + '\'' + ", price=" + price + ", isBorrow=" + ((isBorrow)?"已借出":"未借出") + '}'; } }

注意:
在 Java 中也有 Book类,而我们需要使用的我们自定义的 Book 类,在实例>化的时候需要导入正确的包(import Book.Book; ),否则会报错
2.1.2 书架类(BookList)
  • 书架中包含书本的数目(bookCount)和各种 Book 类型的书(创造Book类型的 books 数组)
  • 提供 BookList 类的无参的构造方法来初始化 books 数组(在这里放了三本书),书本的数目(bookCount)为3
  • 提供 returnBook 方法,返回 books 数组中下标为 i 的书籍,例如打印书籍功能就需要该方法访问到每本书籍
  • 提供 setBooks 方法,在books 数组中下标为 num 的位置放置书籍,例如增加书籍功能中就需要在遍历完 books 数组来确认书架上没有想要增加的书的情况下,在下标为 bookCount 的位置放置新增加的书
  • 提供 getBookCount 方法,使外界获取书本的数目
  • 提供 setBookCount 方法,使外界可以改变书本的数目,例如删除书籍功能中就需要在遍历完 books 数组来确认书架上有想要删除的书的情况下,将书籍删除,通过该方法将书本数目减一
package Book; public class BookList {private int bookCount; public Book[] books = new Book[20]; public BookList() {books[0] = new Book("Java","C张三",32.8); books[1] = new Book("C++","B李四",59.0); books[2] = new Book("Python","A王五",29.8); this.bookCount = 3; } //返回在i下标处的书本 public Book returnBook(int i) {return books[i]; } //在num位置放置一本书 public void setBooks(Book book,int num) {books[num] = book; } //返回此时书本的本数 public int getBookCount() {return bookCount; } //改变书本的数目 public void setBookCount(int bookCount) {this.bookCount = bookCount; } }

2.2 Users 包
无论是普通用户还是图书管理员都共同属于户,因此他们共同的信息就可以写在用户类中,来继承用户类,从而达到代码的重用
2.2.1 用户类(User)
  • 用户都拥有的变量是用户名字
  • 提供用户类含有一个参数(name)的构造方法
  • 提供抽象方法 menu,因为普通用户和图书管理员的菜单是不同的,重写 menu,当发生向上转型的时候,通过重写的 menu 可以访问到不同类型的用户的菜单,实现了多态
  • 该类中还包含着 IFunction(接口)类型的数组 iFunctions,因为不同类型的用户可以实现的功能是不同的,可以在子类帮父类进行构造方法的构造时定义不同内容的 iFunctions
  • 提供 getFunction 方法,对 bookList(通过 BookList 类实例化的对象即书架) 实现 iFunctions 数组下标为 choice 的功能
package Users; import Book.BookList; import Function.IFunction; public abstract class User {//用户姓名 protected String name; //该数组可以接收不同类型用户的功能 protected IFunction[] iFunctions; //构造方法 public User(String name) {this.name = name; } //需要被重写以达到多态,拿到不同菜单的抽象方法 menu public abstract int menu(); //choice 表示iFunctions数组的下标,choice 不同,实现的功能不同 public void getFunction(int choice,BookList bookList) {this.iFunctions[choice].work(bookList); } }

2.2.2 普通用户类(NormalUser)
  • 普通用户类继承了用户类,帮父类进行构造的时候初始化父类的 iFunctions 的数组
  • 重写父类的抽象方法 menu
package Users; import Function.*; import java.util.Scanner; public class NormalUser extends User{public NormalUser(String name) {super(name); //初始化父类的 iFunctions 的数组 iFunctions = new IFunction[]{new ExitFunction(), new FindFunction(), new BorrowFunction(), new ReturnFuntion() }; } // 重写父类的抽象方法 menu @Override public int menu() {System.out.println("=========普通用户菜单=========="); System.out.println("Hello " + this.name + " 欢迎来到图书管理系统"); 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); while (true) {int choice = scanner.nextInt(); if (choice >= 0 && choice <= 3) {return choice; } else {System.out.println("选择错误,请重新选择!"); } } } }

2.2.3 图书管理员类(Administrator)
和普通用户类方法一样
package Users; import Function.*; import java.util.Scanner; public class Administrator extends User{public Administrator(String name) {super(name); //初始化父类的 iFunctions 的数组 iFunctions = new IFunction[] {new ExitFunction(), new FindFunction(), new AddFunction(), new DelFunction(), new DisplayFunction(), new SortFunction() }; } // 重写父类的抽象方法 menu @Override public int menu() {System.out.println("=========图书管理员菜单=========="); System.out.println("Hello " + this.name + " 欢迎来到图书管理系统"); System.out.println("1.查找书籍"); System.out.println("2.增加书籍"); System.out.println("3.删除书籍"); System.out.println("4.打印书籍"); System.out.println("5.整理书籍"); System.out.println("0.退出系统"); System.out.println("请选择你想要进行的操作"); Scanner scanner = new Scanner(System.in); while (true) {int choice = scanner.nextInt(); if (choice >= 0 && choice <= 5) {return choice; } else {System.out.println("选择错误,请重新选择!"); } } } }

2.3 Function 包
实际上功能往往是放在最后完成的,除了功能以外的部分就是整个项目的框架,完成了框架后,再来实现功能就很简单了。
2.3.1 IFunction 接口
【JavaSE|【Java】图书管理系统(菜鸟版)】实现接口 IFunction
package Function; import Book.BookList; public interface IFunction {void work(BookList bookList); }

2.3.2 查找书籍(FindFunction)
遍历 bookList 查看是否有想要查找的书籍
package Function; import Book.BookList; import java.util.Scanner; public class FindFunction implements IFunction{@Override public void work(BookList bookList) {System.out.println("请输入你想要查找的书籍:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); int num = bookList.getBookCount(); for (int i = 0; i < num; i++) {if (name.equals(bookList.returnBook(i).getName())) {System.out.println(bookList.returnBook(i)); System.out.println("查找成功!"); return; } } System.out.println("不存在这本书!"); } }

2.3.3 增加书籍 (AddFunction)
  • 重写接口中的 work 方法
  • 遍历 bookList 里的所有书,当不存在该书时,就实例化一本书,通过 setBooks 方法将书放到书架上,通过 setBookCount 方法使书本数目加一
package Function; import Book.Book; import Book.BookList; import java.util.Scanner; public class AddFunction implements IFunction{@Override public void work(BookList bookList) {System.out.println("想要添加的书籍的名字:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); int num = bookList.getBookCount(); for (int i = 0; i < num; i++) {if (name.equals(bookList.returnBook(i).getName())) {System.out.println("已经存在该本书!"); return; } } System.out.println("书籍的作者:"); String author = scanner.nextLine(); System.out.println("书籍的价格:"); Double price = scanner.nextDouble(); Book book = new Book(name,author,price); bookList.setBooks(book,num); bookList.setBookCount(num + 1); System.out.println("增加成功!"); } }

2.3.4 删除书籍(DelFunction)
  • 总体思想和增加一本书差不多
  • 当在 bookList 中找到想要删除的书籍时(例如书籍所在的下标为 i ),那么就得到下标为 i + 1 的书籍使之覆盖下标为 i 处的书籍,i ++ ,切记i 的值一定要小于书本的数目减一,否则会访问到非书籍的部分(越界)
  • 删除成功后一定要记得将书本的数目减一
package Function; import Book.BookList; import java.util.Scanner; public class DelFunction implements IFunction{@Override public void work(BookList bookList) {System.out.println("请输入你想要删除的书籍:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); int num = bookList.getBookCount(); for (int i = 0; i < num; i++) {if (name.equals(bookList.returnBook(i).getName())) {for (int j = i; j < num - 1; j++) {bookList.setBooks(bookList.returnBook(j + 1),j); } System.out.println("删除成功!"); bookList.setBookCount(num - 1); return; } } System.out.println("不存在这本书!"); } }

2.3.5 打印书籍(DisplayFunction)
package Function; import Book.BookList; public class DisplayFunction implements IFunction{@Override public void work(BookList bookList) {int num = bookList.getBookCount(); for (int i = 0; i < num; i++) {System.out.println(bookList.returnBook(i)); } } }

2.3.6 整理书籍(SortFunction)
  • 整理书籍即对 BookList 上的书籍以自己的想要的标准进行排序,这里就用到了 Comparator 接口,具体用法在生动例子详解接口这一小节中有所介绍,这里就不多言
  • SortFunction 类中定义一个 Comparator 接口类型的数组 comparators,通过该数组来选择比较器
package Function; import Book.Book; import Book.BookList; import java.util.Arrays; import java.util.Comparator; import java.util.Scanner; class NameComparator implements Comparator {@Override public int compare(Book o1, Book o2) {return o1.getName().compareTo(o2.getName()); } } class AuthorComparator implements Comparator {@Override public int compare(Book o1, Book o2) {return o1.getAuthor().compareTo(o2.getAuthor()); } } class PriceComparator implements Comparator {@Override public int compare(Book o1, Book o2) {return (int)(o1.getPrice()-o2.getPrice()); } } public class SortFunction implements IFunction{public Book[] array(Book[] book,int num) {Book[] books = new Book[num]; for (int i = 0; i < num; i++) {books[i] = new Book(book[i].getName(),book[i].getAuthor(),book[i].getPrice()); } return books; } @Override public void work(BookList bookList) {Scanner scanner = new Scanner(System.in); Comparator[] comparators = new Comparator[] {new NameComparator(), new AuthorComparator(), new PriceComparator() }; while (true) {System.out.println("请问想要以什么标准进行排序:0.name 1.author 2.price 3.isBorrow"); int choice = scanner.nextInt(); if (choice >= 0 && choice <= 2 ) {Book[] newBooks = array(bookList.books,bookList.getBookCount()); Arrays.sort(newBooks, comparators[choice]); for (int i = 0; i < newBooks.length; i++) {System.out.println(newBooks[i]); } System.out.println("排序完成!"); return; }else {System.out.println("选择错误!"); } } } }

注意:
  • Arrays.sort(参数一,参数二); 参数一是需要进行排序的对象,参数二是使用到的比较器
  • 切记!!不可以将 bookList 里的 books 直接传到参数一中,因为 books 中可以放20本书,但是真正初始化的却不足20本(例如该数组中最初只有3本书,那么剩下17个未初始化的下标的内容全是null),用比较器就会发生空指针异常
  • 因此可以通过 array 方法来获取到 books 中真正被初始化的内容
山居因为大意了,在此坑中躺了蛮久。。。
JavaSE|【Java】图书管理系统(菜鸟版)
文章图片

2.3.7 借阅书籍(BorrowFunction)
思路大同小异,遍历 bookList 中的书,借阅即将找到的那本书的借阅状态改为 true,如果该书的借阅状态在借之前就是 true ,说明该书已经被借走了
package Function; import Book.BookList; import java.util.Scanner; public class BorrowFunction implements IFunction{@Override public void work(BookList bookList) {System.out.println("请输入你想要借阅的书籍:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); int num = bookList.getBookCount(); for (int i = 0; i < num; i++) {if (name.equals(bookList.returnBook(i).getName())) {if (bookList.returnBook(i).getBorrow()) {System.out.println("该书已被借阅"); return; } bookList.returnBook(i).setBorrow(true); System.out.println("借阅成功!"); return; } } System.out.println("不存在这本书!"); } }

2.3.8 归还书籍(ReturnFunction)
归还思路与借阅同
package Function; import Book.BookList; import java.util.Scanner; public class ReturnFuntion implements IFunction{@Override public void work(BookList bookList) {System.out.println("请输入你想要归还的书籍:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); int num = bookList.getBookCount(); for (int i = 0; i < num; i++) {if (name.equals(bookList.returnBook(i).getName())) {if (!bookList.returnBook(i).getBorrow()) {System.out.println("未借阅过此书"); return; } bookList.returnBook(i).setBorrow(false); System.out.println("归还成功!"); return; } } System.out.println("不存在这本书!"); } }

2.3.9 退出系统(ExitFUnction)
当从键盘中读入一个0时成功退出系统
package Function; import Book.BookList; public class ExitFunction implements IFunction{@Override public void work(BookList bookList) {System.out.println("成功退出系统!"); System.exit(0); } }

2.4 Main类
  • 实例化一个 BookList 类的对象,创造一个书架 bookList
  • 提供 login 方法,该方法中通过不同的选择返回不同的结果,发生向上转型,使 user 访问到不同的菜单
  • 通过菜单进行选择功能,返回的值传入 getFunction 方法中,获取不同的功能
import Book.BookList; import Users.Administrator; import Users.NormalUser; import Users.User; import java.util.Scanner; public class Main {public static User login() {System.out.println("请输入你的姓名:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); System.out.println("请选择你的身份:1=》管理员 0=》普通用户"); while (true) {int choice = scanner.nextInt(); if (choice == 1) {return new Administrator(name); }else if (choice == 0) {return new NormalUser(name); }else {System.out.println("选择错误,请重新输入!"); } } } public static void main(String[] args) {BookList bookList = new BookList(); User user = login(); while (true) {int choice = user.menu(); user.getFunction(choice,bookList); } } }

讲到这儿,一切联系了起来。。。。
JavaSE|【Java】图书管理系统(菜鸟版)
文章图片

三、项目总结 JavaSE|【Java】图书管理系统(菜鸟版)
文章图片

没啥好总结的,我知道的内容都老实交代了,没明白的大兄弟,咱再看一遍。。。
或者来复习复习
【Java】剖析类和对象
【Java】包与继承
【Java】多态与抽象类
【Java】生动例子详解接口
散了散了。。。。。。

    推荐阅读