目录
一、项目功能要求与设计思路
1、图书管理系统的功能要求
作为我们平时认知的基本图书管理系统,最起码要有使用者和管理者两个身份。对应不同的身份,对其图书会进行不一样的操作。
在登陆图书系统的时候,也得设计一个用户名相关的功能,但在这个小项目中不会实现太过复杂的功能,以基础的语法来实现。此处我们可以设计一个输入用户名,欢迎进入的提示语,之后通过输入具体的用户身份,来进行图书管理。
使用者对应可以进行(1)借阅图书(2)归还图书(3)查询图书(4)退出系统,这几个操作;
而管理者可以进行(1)新增图书(2)删除图书(3)显示图书(4)查询图书(5)退出系统这几个操作。
2、设计思路
图书管理设计思路图:
3、实现结果展示 
二、图书管理的基本框架
1、创建书和书架
作为图书管理,那就需要书和书架这两个类。
首先创建一个book包来存放,书Book和书架BookList这两个类。
(1)定义Book类中的属性和方法
【注意】:Java中所有的类都有一个公共的父类就是Object类,一个类只要没有明显的继承一个类,则肯定是Object的子类。
(2)定义BookList中的属性和方法
BookList类相当于是书架,里面是用存放书籍的。
那么作为书架,对应的一定会有一定的容量,总不可能可以一直增添书到书架上去。
我们首先可以先定义一个书的数组,数组长度可以自己定。(数组里的每一个元素都是书类)存放一本书时,会在对应的数组下标位置实例化一个书的对象。
Book []books=new Book[10];
//此处定义一个长度为10的Book数组
相对应的我们还需要定义书架上书的数量(bookListSize)
private int bookListSize;
//书的数量,后续需根据对应书的数量,对书架上的书进行操作
而作为书架,一开始我们可以先在书架里放几本书,可以通过调用定义的BookList构造方法,来初始化书架内的书,并通过实例化Book对象,调用Book类中的构造方法来初始化书的信息,相当于就在书架上存放了书。
public BookList() {
books[0]=new Book("西游记","吴承恩",49,"小说");
books[1]=new Book("水浒传","施耐庵",50,"小说");
books[2]=new Book("三国演义","罗贯中",45,"小说");
this.bookListSize=3;
}
2、创建用户
首先创建一个user的包
图书管理用户分为(1)管理员(2)普通用户,两个身份。
由于当我们选择不同的身份时,操作的系统(也就是操作的功能)也是不一样的。
此时我们可以用到多态的知识,定义一个父类User,让子类AdminUser和OrdinaryUser继承User。
之后,让父类的引用指向你所选择的子类对象(发生向上转型),再通过调用重写的方法来实现相关的操作。
(1)定义User类
(2)定义 AdminUser类
对于打印的操作界面,是在AdminUser和OrdinaryUser中实现,那么根据前面User中定义的抽象方法,我们必须在子类中重写该方法,从而达到多态的效果。
之后通过输入对应下标的数字,返回其choice给User中的doOperation进行操作即可。
退出系统功能,我们可以将其设置为接口数组下标0的位置,其他的操作功能依次对应。
打印菜单方法:
@Override
public int menu() {
System.out.println("=============================");
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.退出系统");
System.out.println("请输入你要进行的操作:>");
Scanner scanner=new Scanner(System.in);
int choice =scanner.nextInt();
System.out.println("=============================");
return choice;
}
(3)定义OrdinaryUser类
该普通用户OrdinaryUser的定义和上面的管理员类AdminUser一样,只是在打印操作菜单和构造方法内稍作进行修改即可.
构造方法:
public OrdinaryUser(String name) {
super(name);
iOpeartions=new IOpeartion[]{
new ExitOperation(), //退出系统
new BorrowOperation(), //借阅图书
new ReturnOperation(), //归还图书
new FindOperation() //查询图书
};
}
打印菜单方法:
@Override
public int menu() {
System.out.println("=============================");
System.out.println("欢迎"+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);
int choice =scanner.nextInt();
System.out.println("=============================");
return choice;
}
3、实现图书管理功能
从前面可知,我们可以创建一个接口和多个操作类,让这些类来实现接口功能。通过接口我们可以实现多态来对书架进行各种的操作。
首先先创建一个iOperation包,之后在包内定义接口和类。
其中一共7种操作,对应7个类。
接口内需定义一个抽象方法work,参数为BookList类(需要对书架进行操作,因此传一个书架对象过去)。
public interface IOpeartion {
public abstract void work(BookList bookList);
}
下面将对各个操作类进行定义,但我们先不对其进行功能的代码实现,我们得先把具体的框架构建出来。
①AddOperartion
package iOperation;
import book.BookList;
public class AddOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
System.out.println("新增图书");
}
}
②BorrowedOperation
package iOperation;
import book.BookList;
public class BorrowedOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
System.out.println("借阅图书");
}
}
③DeleteOperation
package iOperation;
import book.BookList;
public class DeleteOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
System.out.println("删除图书");
}
}
④DisplayOperation
package iOperation;
import book.BookList;
public class DisplayOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
System.out.println("显示图书");
}
}
⑤ExitOperation
package iOperation;
import book.BookList;
public class ExitOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
System.out.println("退出系统");
}
}
⑥FindOperation
package iOperation;
import book.BookList;
public class FindOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
System.out.println("查询图书");
}
}
⑦ReturnOperation
package iOperation;
import book.BookList;
public class ReturnOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
System.out.println("归还图书");
}
}
4、Main
前面说了这么多,作为一个程序怎么说都得要有一个入口Main。
我们在Main中,需要实例化一个书架对象(没有书架还怎么进行下面的操作)和定义一个登录界面。
登录界面通过定义一个静态方法即可
其中进行的一系列操作可以用一个while循环起来,之后即可不断地进行书籍操作,直到我们选择退出系统后才结束。
import book.BookList;
import 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)管理员 (2)普通用户");
int choice=scanner.nextInt();
if(choice==1){
return new AdminUser(name);
} else{
return new OrdinaryUser(name);
}
}
public static void main(String[] args) {
BookList bookList=new BookList();
User user=login(); //此处会发生向上转型(login()返回的是一个子类对象)
while(true){
int choice=user.menu(); //通过user类中的menu()进行操作选择
user.doOperation(choice,bookList);//根据所选的操作进行执行
}
}
}
二、图书管理功能地实现
(1)新增图书功能
想要在书架中新增新的书,我们首先得先实例化一个新的书对象,并对其进行初始化。
通过Scanner输入所需要地信息(书名、作者名、价格、类型)后,将其传到构造方法内。
信息处理好后,接下来就是得修改书架书的数量(setBookListSize)和放置书(setBooks)。
package iOperation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class AddOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要新增的书名:");
String name=scanner.nextLine();
System.out.println("请输入书的作者名:");
String author=scanner.nextLine();
System.out.println("请输入书的价格:");
int price=scanner.nextInt();
System.out.println("请输入书的类型:");
String type=scanner.next();
int currentSize=bookList.getBookListSize();
Book book=new Book(name,author,price,type);//实例化一本新的书
bookList.setBooks(currentSize,book); //放置新书
bookList.setBookListSize(currentSize+1); //修改书的数量
System.out.println("新增图书《"+name+"》成功!");
}
}
(2)查找图书功能
要实现查找图书的功能,需要我们通过输入书名,来对书数组进行遍历查找是否存在该书,存在则打印书的信息,不存在则打印不存在。
package iOperation;
import book.BookList;
import java.util.Scanner;
public class FindOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要查询的书名:");
String name=scanner.nextLine();
int currentSize=bookList.getBookListSize();
for (int i = 0; i < currentSize; i++) {
if(bookList.getBook(i).getName().equals(name)){
System.out.println("找到了该书");
System.out.println(bookList.getBook(i));
return;
}
}
System.out.println("找不到该书");
}
}
(3)借阅图书功能
借阅图书刚开始需要做的代码实现跟上面的查询图书相似,都是需要先查找是否存在此书,再进行操作。直到遍历判断前的代码都是一样的。
package iOperation;
import book.BookList;
import java.util.Scanner;
public class BorrowOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要借阅的书名:");
String name=scanner.nextLine();
int currentSize=bookList.getBookListSize();
for (int i = 0; i < currentSize; i++) {
if(bookList.getBook(i).getName().equals(name)){
if(bookList.getBook(i).isBollowed()==false){
System.out.println("借阅成功!");
bookList.getBook(i).setBollowed(true);
return;
} else{
System.out.println("此书已被借走!");
return;
}
}
}
System.out.println("找不到此书!");
}
}
(4)归还图书功能
归还图书系统只需在借阅图书的基础上,将遍历数组的语句内部更改为判断是否有此书存在后,将该书的状态修改为未借阅状态即可。(通过booklist.getBook(i).setBollowed(false)修改)
package iOperation;
import book.BookList;
import java.util.Scanner;
public class ReturnOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要归还的书名:");
String name=scanner.nextLine();
int currentSize=bookList.getBookListSize();
for (int i = 0; i < currentSize; i++) {
if(bookList.getBook(i).getName().equals(name)){
System.out.println("归还成功");
bookList.getBook(i).setBollowed(false);
return;
}
}
System.out.println("书架上原本没有此书!");
}
}
(5)显示图书功能
显示图书功能只需通过定义的书数量currentSize,然会对数组进行遍历,调用booklist中的getBook(i)来回获取对应的书,最后输出书的信息即可。
package iOperation;
import book.BookList;
public class DisplayOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
int currentSize=bookList.getBookListSize();
for (int i = 0; i < currentSize; i++) {
System.out.println(bookList.getBook(i));
}
}
}
(6)退出系统功能
为了避免内存泄漏,我们将书架的数据全部销毁掉(利用存放书的方法,将数组内部全部置为空)
使用System.exit(0) 正常退出程序
package iOperation;
import book.BookList;
public class ExitOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
System.out.println("图书管理系统已退出!");
int currentSize= bookList.getBookListSize();
for (int i = 0; i <currentSize; i++) {
bookList.setBooks(i,null);
}
System.exit(0);
}
}
(7)删除图书功能*
此功能相较于前面几个功能,会稍微有些难实现。
首先看到删除二字,可以联想到借助数组中后者覆盖前者的方法,将想要删除的元素进行覆盖,从而实现删除的效果。
要实现这个效果,需要两个for循环,第一个for循环查询是否该书存在;第二for循环进行覆盖操作,进行覆盖操作需要所删除书的下标位置i和当前数组的长度currentSize。
那么我们的第二次循环,得根据找到对应书的下标i为起始条件,然后以currentSize-1为范围来进行覆盖操作。
覆盖操作,只需先实例化当前下标的下一个位置的书,然后通过调用setBooks(int s,Book book)将后者books[j+1]覆盖于前者books[j]
if(bookList.getBook(i).getName().equals(name)){
for (int j = i; j <currentSize-1; j++) {
Book book=bookList.getBook(j+1);
bookList.setBooks(j,book);
}
}
执行覆盖之后,还需通过调用booklist中的setBookListSize()方法修改书架内书的数量,毕竟都已经删除了书,自然都修改书的数量。
package iOperation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class DeleteOperation implements IOpeartion{
@Override
public void work(BookList bookList) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要删除的书名:");
String name=scanner.nextLine();
int currentSize=bookList.getBookListSize();
for (int i = 0; i < currentSize; i++) {
if(bookList.getBook(i).getName().equals(name)){
for (int j = i; j <currentSize-1; j++) {
Book book=bookList.getBook(j+1);
bookList.setBooks(j,book);
}
bookList.setBookListSize(currentSize-1);
System.out.println("删除成功!");
return;
}
}
System.out.println("找不到此书");
}
}