前言:
对于图书管理系统,小编进行了一次完整的模拟,小编将从我的思路尽量将过程呈现出来,希望能够帮到屏幕前的你。^ . ^
1.实现结果
在图书管理系统中,我们规定两类用户,普通用户以及管理员。他们分别执行各自的功能项目。
欢迎GGBondlctrl来到管理员菜单
------------------
1.查找图书
2.新增图书
3.删除图书
4.显示图书
0.退出系统
------------------
欢迎GGBondlctrl来到普通成员菜单
------------------
1.查找图书
2.借阅图书
3.归还图书
0.退出系统
------------------
通过输入对应用户的对应的数值,可以进行添加,删除,显示等操作。
例如:管理员菜单的新增书籍示范:
请输入你的操作
2
新增书籍
请输入书名:
红楼梦
请输入作者:
曹雪芹
请输入价格:
56
请输入书的类型:
小说
已经成功添加你的书籍
再次输入显示书籍的指令,就会发现书籍已经添加进去了
请输入你的操作
4
显示书籍
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=未被借出}
Book{bookName='水浒传', author='施耐庵', price=59, types='小说', isBorrow=未被借出}
Book{bookName='三国演义', author='罗贯中', price=67, types='小说', isBorrow=未被借出}
Book{bookName='红楼梦', author='曹雪芹', price=54, types='小说', isBorrow=未被借出}
此时我们发现我们添加的《红楼梦》已经添加进去了。
2.功能的分类
1.小编在这里分了三个包来进行功能的分类,非别是Book,Operation,User。既然是图书管理,那么就有书,和书架,所以小编设置了book包,如上图显示,功能为一个包,用户一个包。
在book包里,小编设置了book类来存储成员变量的声明,以及booklist来表示书架来存书籍,操作包里就是各个操作,用户包里就进行两者用户的编写,以及主函数。
3.代码实现过程
3.1.book类
在book类中我们肯定要进行图书属性的声明,因为是封装所以小编这里使用了private修饰符修饰成员变量,这里注意借出与不借出,小编这里默认的是为false为没有被借出。
代码如下:
public class Book {
private String bookName;
private String author;
private int price;
private String types;
private boolean isBorrow;
public Book(String bookName, String author, int price, String types, boolean isBorrow) {
this.bookName = bookName;
this.author = author;
this.price = price;
this.types = types;
this.isBorrow = isBorrow;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getTypes() {
return types;
}
public void setTypes(String types) {
this.types = types;
}
public boolean isBorrow() {
return isBorrow;
}
public void setBorrow(boolean borrow) {
isBorrow = borrow;
}
}
这里小编还进行了构造函数的声明,以及get与set函数,通过快捷键alt+insert来进行编写,
(为啥要用get与set函数):因为我们的成员变量是私有的,要想使用就得传入set函数通过get函数来调用对应的成员变量。
3.2.booklist类
在此类中小编创建了一个Book类的books的数组对象。在构造函数中存入了三本书分别在,0,1,2,下标。
public class Booklist {
Book []books=new Book[10];
private int sizeBook;
public Booklist(){
this.books[0]= new Book("西游记","吴承恩",57,"小说",false);
this.books[1]= new Book("水浒传","施耐庵",59,"小说",false);
this.books[2]=new Book("三国演义","罗贯中",67,"小说",false);
sizeBook=3;
}
这里还要设置数组的长度,,以及取书和拿书的方法,方便之后的操作类进行对应的操作
public int getSizeBook() {
return sizeBook;
}
public void setSizeBook(int sizeBook) {
this.sizeBook = sizeBook;
}
public Book getBook(int indexBook){
return books[indexBook];
}
public void setBook(int indexBook,Book book){
books[indexBook]=book;
}
注意:取书是getbook返回的类型是Book类型,通过输入下标值,返回对应的书籍信息。
存书也是一样的,通过输入下标以及存入的书,来完成对应位置房对应的书。
3.3.操作类
在操作类中,我们先在各个类实现work方法输出打印的方法,由于都存在一样的方法,就可以设置一个接口,其他类来实现这个接口。
public class borrowBook implements Ioperation {
@Override
public void work(Booklist booklist) {
System.out.println("请输入你要借的书名:");
例如,我们将这借书的操作先输出出来,其他过程之后完善。其他操作类似;
以及接口:
public interface Ioperation {
void work(Booklist booklist);
}
那么我们的操作类就先放在这里,进入下一个类。
3.4.用户类
1.在管理员类中,我们要实现输入名字,以及输入相关的数字进行对应操作方法的打印实现,
Scanner sc=new Scanner(System.in);
public Administor(String name){
super(name);
this.ioperation=new Ioperation[]{new exitBook(),new selectBook(),new addBook(),new deletBook()
,new showBook() };
}
public int meau(){
System.out.println("欢迎"+name+"来到管理员菜单");
System.out.println("------------------");
System.out.println("1.查找图书");
System.out.println("2.新增图书");
System.out.println("3.删除图书");
System.out.println("4.显示图书");
System.out.println("0.退出系统");
System.out.println("------------------");
System.out.println("请输入你的操作");
int num=sc.nextInt();
return num;
}
public void open(int choice,Booklist booklist){
ioperation[choice].work(booklist);
}
1. 小编这里用scanner函数实现输入名字。
2.为啥构造函数里有super呢,因为小编这里是将管理员类继承于User父类,实现父类构造方法的重写,这里后面再说
3.这里通过接口类实现将各个功能通过数组存储。(这里是个向上转型)要看输入的数值来对应各对象功能的下标。
4.菜单方法,是为了方便了解对应数字的功能。
5.open方法的参数是输入的数字,以及书架;这里通过ioperation接收传递的数,来表对应的new操作对象,又通过操作对象实现对应的操作work。
例如:加入输入1,则通过上面:
this.ioperation=new Ioperation[] {new exitBook(),new selectBook(),new addBook(),new deletBook(),new showBook() };发现,对应的是new exitBook则再次调用它的work方法
public class exitBook implements Ioperation { @Override public void work(Booklist booklist) { System.out.println("退出系统"); System.exit(0); } }就完成了对应操作的交互响应
2. 在普通用户类也是一样的:
public class Nomaluser extends User{
Scanner sc=new Scanner(System.in);
public Nomaluser(String name){
super(name);
this.ioperation=new Ioperation[]{
new exitBook(),
new selectBook(),
new borrowBook(),
new leadBook()
};
}
public int meau(){
System.out.println("欢迎"+name+"来到普通成员菜单");
System.out.println("------------------");
System.out.println("1.查找图书");
System.out.println("2.借阅图书");
System.out.println("3.归还图书");
System.out.println("0.退出系统");
System.out.println("------------------");
System.out.println("请输入你的操作");
int num=sc.nextInt();
return num;
}
public void open(int choice,Booklist booklist){
ioperation[choice].work(booklist);
}
}
这里要注意两者的操作不一样。
3.这里就是User父类的实现了,小编在上述的super和this.ioperation都有了很好的解释,
public abstract class User {
Ioperation ioperation[];
public String name;
public User(String name){
this.name=name;
}
abstract int meau();
abstract void open(int choice, Booklist booklist);
}
这里声明了一个Ioperation类的ioperation的数组,就有了子类的各个功能的实现,这里设置了一个父类的有参构造方法,实现名字的打印,那么子类就应该进行重写。meau和open都是抽象方法,那么子类都应该重写。
3.5.主函数
代码如下:
public class Main {
public static User logn() {
Scanner sc=new Scanner(System.in);
System.out.println("请输入你的名字:");
String name=sc.nextLine();
System.out.println("请输入你的身份1--》管理员,2--》普通用户");
int choice=sc.nextInt();
if (choice==1){
Administor administor=new Administor(name);
return administor;
}
else {
Nomaluser nomaluser=new Nomaluser(name);
return nomaluser;
}
}
public static void main(String[] args) {
Booklist booklist=new Booklist();
User user=logn();
while (true){
int choice= user.meau();
user.open(choice,booklist);
}
}
}
注意:1.小编在这里重写了一个静态方法,通过输入的值来判定对应的身份,如果是1,那么就是管理身份,返回管理的对象,如果是2,那么就返回普通用户的对象,那么我们应该用啥来接收呢,此时就要用一个向上转型的思想,我们就用父类User类来接收他们的对象,然后通过主函数入口,将对象给user,通过user来调用对应的open方法。这里还得有booklist的对象的声明。
4.代码实现完善
在上述过程中我们只是完成对应功能的打印。
例如:
请输入你的名字:
GGBondlctrl
请输入你的身份1--》管理员,2--》普通用户
1
欢迎GGBondlctrl来到管理员菜单
------------------
1.查找图书
2.新增图书
3.删除图书
4.显示图书
0.退出系统
------------------
请输入你的操作
1
查找书籍
那么接下来就要进行对应操作的功能的完善。
4.1.新增书籍
代码如下:
public class addBook implements Ioperation {
@Override
public void work(Booklist booklist) {
System.out.println("新增书籍");
Scanner sc=new Scanner(System.in);
System.out.println("请输入书名");
String name= sc.nextLine();
System.out.println("请输入作者");
String author= sc.nextLine();
System.out.println("请输入价格");
int price=sc.nextInt();
sc.nextLine();
System.out.println("请输入书的类型");
String type=sc.nextLine();
Book book=new Book(name,author,price,type,false);
int size=booklist.getSizeBook();
booklist.setBook(size,book);
size++;
booklist.setSizeBook(size);
System.out.println("已经成功添加你的书籍");
}
}
在这里我们需要输入对应的作者,书籍名字,价格等等(注意:在nextInt方法会留下回车键或者换行符在输入流中,nextLine()会当做一行内容读取,所以解决办法时在之前在加一行nextLine消耗掉多于的换行符或回车键。)在将输入的内容传入book对象中去。通过size表示多少本书,在setBook方法中存书(位置,以及book这本书)默认的是存在数组的末尾。然后size加一,成为下一个存书的下标。
4.2.借阅书籍
代码如下:
public void work(Booklist booklist) {
System.out.println("请输入你要借的书名:");
Scanner sc=new Scanner(System.in);
String name=sc.nextLine();
int size= booklist.getSizeBook();
for (int i = 0; i <size-1 ; i++) {
Book book=booklist.getBook(i);
if (book.getBookName().equals(name)){
if(book.isBorrow()==true){
System.out.println("这本书已经被借出了");
break;
}
System.out.println("找到了你要借阅的书籍");
book.setBorrow(true);
break;
}
}
首先我们要通过输入书名,然后再“书架上遍历所有的书籍”,通过名字进行对比,实现找到功能,并将书籍的借出状况标为(被借出)。
小编这里通过循环遍历,从0下标的书找,将对应下标的值对应的书传到book中,通过equals来进行名字对比。若找到了就将借出状态改为true.并且在输出借阅之前判断这本书是否已经被借出,表示不能再次借阅。
实例如下:
请输入你要借的书名:
西游记
找到了你要借阅的书籍
那么此时我们可以看这本书的状态
1
查找书籍
请输入你要查找的书
西游记
找到了你要的书
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=已被借出}
4.3.删除图书
代码如下:
public void work(Booklist booklist) {
System.out.println("删除书籍");
System.out.println("请输入你要删除的书籍");
Scanner sc = new Scanner(System.in);
String name = sc.nextLine();
int size = booklist.getSizeBook();
int index=-1;
for (int i = 0; i < size ; i++) {
Book book = booklist.getBook(i);
if (book.getBookName().equals(name)) {
System.out.println("找到了你要删除的书");
index=i;
break;
}
}
if(index==-1){
System.out.println("没有找到你要的书");
}
for (int j = 0; j < size - 1; j++) {
Book book1 = booklist.getBook(index + 1);
booklist.setBook(index, book1);
index++;
}
booklist.setSizeBook(size-1);
System.out.println("删除成功");
和上述一样,通过遍历找到要删除的书以及下标,通过下标加1将后一本书传到删除书的位置,进行覆盖,并且size表示的书的数目减一,为遍历循环条件准备。这里小编还设置了变量表示来控制提示语句的输出。
实例展示:
3
删除书籍
请输入你要删除的书籍
西游记
找到了你要删除的书
删除成功
显示图书,观察是否删除
4
显示书籍
Book{bookName='水浒传', author='施耐庵', price=59, types='小说', isBorrow=未被借出}
Book{bookName='三国演义', author='罗贯中', price=67, types='小说', isBorrow=未被借出}
此时发现西游记这本书已经被删除
4.4.退出系统
代码如下:
public void work(Booklist booklist) {
System.out.println("退出系统");
System.exit(0);
}
System.exit(0)表示return 0;
实例展示:
请输入你的操作
0
退出系统Process finished with exit code 0
4.5. 归还书籍
代码如下:
public void work(Booklist booklist) {
System.out.println("归还书籍");
System.out.println("请输入你要借的书名:");
Scanner sc=new Scanner(System.in);
String name=sc.nextLine();
int size= booklist.getSizeBook();
for (int i = 0; i <size-1 ; i++) {
Book book=booklist.getBook(i);
if (book.getBookName().equals(name)){
if(book.isBorrow()==false){
System.out.println("这本书已经被归还了");
break;
}
System.out.println("找到了你要归还的书籍");
book.setBorrow(false);
break;
}
else {
System.out.println("没有找到你归还的书");
}
}
和借阅一样,只不过将借出状态改一下就行,还是通过循环找到这本书,比较名字,在改变借出状态之前,判断这本书是否已经被归还了。若没有,则改变这本书的借出状态。
实例展示:
若已经归还:
3
归还书籍
请输入你要归还的书名:
西游记
这本书已经被归还了
若没有归还:
西游记
找到了你要的书
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=已被借出}
归还后:
西游记
找到了你要的书
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=未被借出}
4.6.查找书籍
代码如下:
public void work(Booklist booklist) {
System.out.println("查找书籍");
Scanner sc=new Scanner(System.in);
System.out.println("请输入你要查找的书");
String name=sc.nextLine();
int num=booklist.getSizeBook();
int index=0;
for (int j = 0; j <num ; j++) {
Book book=booklist.getBook(j);
if(book.getBookName().equals(name)){
System.out.println("找到了你要的书");
System.out.println(book);
index=1;
break;
}
}
if(index==0){
System.out.println("没有找到你查找的书");
}
}
通过循环遍历书籍,还是通过名字比较,若一样则打印要找的书籍,并且小编这里也设置了一个变量来控制提示语句的打印。
实例展示:
1
查找书籍
请输入你要查找的书
西游记
找到了你要的书
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=未被借出}
4.7.显示书籍
代码如下:
public void work(Booklist booklist) {
System.out.println("显示书籍");
int length=booklist.getSizeBook();
for (int i = 0; i <length ; i++) {
System.out.println( booklist.getBook(i));
}
}
这个就相对比较简单,通过循环遍历来显示每本书的信息。
这里的 booklist.getBook()就是Book book=booklist.getBook(i)
system.out.println(book)
实例展示:
4
显示书籍
Book{bookName='西游记', author='吴承恩', price=57, types='小说', isBorrow=未被借出}
Book{bookName='水浒传', author='施耐庵', price=59, types='小说', isBorrow=未被借出}
Book{bookName='三国演义', author='罗贯中', price=67, types='小说', isBorrow=未被借出}
5.总结
小编认为图书管理系统,是对我们面向对象编程的一次考验,其中的向上转型多态思想是链接各个功能的重要思想,以及各个部分功能的完善也能够帮助我们对逻辑思维能力的提升。
限于小编能力有限,代码或者解释可能有误,希望各位uu提出宝贵意见。
代码已经上传gitee码云了,想看的uu自取哟Library: 图书管理系统
制作不易,给小编一个小小的赞吧。