目录
对于图书管理系统,通常在登录时会分为两种身份:图书管理员 ,还有普通用户。
对于图书管理者,可以进行删除 图书,添加 图书,查找图书等操作,
那对于普通用户来说,我们可以查找 ,借阅 ,归还等操作。
除了这些,我们还需要对书架上面的书籍进行统一管理,那么我们下面就来介绍一下我们的图书管理系统。
一.功能介绍
用户分为:图书管理员 和普通用户。
书籍统一用一个书架类 进行管理,书类用来定义。
对于图书管理员有查找 ,添加 ,删除 ,显示的功能
对于普通用户有查找 ,借书 ,还书的功能
二.功能实现
1 .首先,我们得定义一个书类,便于后续给书架上的数定义。
java
package book;
//书籍对象
public class Book {
private String name;//书名
private String author;//作者
private int price;//价格
private String type;//类型
private boolean isBorrowed;//是否被借出
public Book(String name, String author, int price, String type) {
this.name = name;
this.author = author;
this.price = price;
this.type = type;
}
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 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 isBorrowed() {
return isBorrowed;
}
public void setBorrowed(boolean borrowed) {
isBorrowed = borrowed;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
(isBorrowed()==true?" 已借阅":" 未借阅")+
// ", isBorrowed=" + isBorrowed +
'}';
}
}
代码解释 :这段代码定义了一个
Book
类,用于表示书籍对象。类中包含了书名、作者、价格、类型和是否被借出的属性。构造器用于初始化书籍的基本信息,默认情况下,书籍是未被借出的。类中提供了 getter 和 setter 方法来访问和修改这些属性。重写的toString()
方法用于输出书籍的信息,其中会根据是否借出显示"已借阅"或"未借阅"。
2 .定义一个书架类,用于存放默认书籍信息,方便后续添加删除书籍等操作。
java
package book;
//书架
public class Booklist {
private Book[] books;//存放书籍
private static final int DEFAULT_SIZE=10;
private int usedSize;//有效书籍的个数
public Booklist(){
this.books=new Book[DEFAULT_SIZE];
this.books[0]=new Book("三国演义","罗贯中",17,"武侠");
this.books[1]=new Book("西游记","吴承恩",18,"神话");
this.books[2]=new Book("红楼梦","曹雪芹",20,"小说");
this.usedSize=3;
}
//获取书籍个数
public int getUsedSize(){
return usedSize;
}
//后期新添书籍个数
public void setUsedSize(int usedSize){
this.usedSize=usedSize;
}
public Book getBook(int Bos){
return books[Bos];
}
public void setBook(int Bos,Book book){
books[Bos]=book;
}
public Book[] getBooks(){
return books;
}
public void setBooks(int index ,Book book){
books[index]=book;
}
public Book getBooks(int index){
return books[index];
}
}
代码解释 :类中包含了一个
Book
类型的数组来存放书籍,以及一个记录有效书籍数量的usedSize
属性。构造器中初始化了一个默认大小为 10 的数组,并且预先存放了三本书籍。类提供了几个方法来访问和修改书架上的书籍,包括获取书籍个数、获取或设置某本书籍、以及获取所有书籍。
3.定义一个抽象用户类,用于作为父类给普通用户和图书管理员继承
java
package user;
import book.Book;
import book.Booklist;
import operation.IOPeration;
public abstract class User {
public String name;
public IOPeration[] ioPerations;
public User(String name){
this.name=name;
}
public abstract int menu();
public void doOperation(int choice , Booklist books){
IOPeration ioPeration=ioPerations[choice];
ioPeration.work(books);
};
}
代码解释 :
User
类中包含两个成员变量:一个是name
(用户的名字),另一个是ioPerations
(操作数组,用于存储用户可执行的操作)。构造方法用于初始化用户的名字。menu()
是一个抽象方法,要求子类实现,用于显示用户的菜单并获取选择。doOperation()
方法接受一个操作选择和书籍列表,通过选择的操作来调用IOPeration
数组中的对应操作,并执行该操作。
4.编写完了用户类,我们就可以编写图书管理员和普通用户的代码了。
图书管理员:
java
package user;
import operation.*;
import java.util.Scanner;
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
this.ioPerations=new IOPeration[]{
new ExitBook(),
new FindBook(),
new AddBook(),
new DelBook(),
new ShowBook()
};
}
@Override
public int menu() {
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("请输入你的操作:");
Scanner scanner=new Scanner(System.in);
int choice=scanner.nextInt();
return choice;
}
}
代码解释 :这段代码定义了一个
AdminUser
类,它继承自User
类,表示管理员用户。管理员用户有一些特定的操作,如查找图书、添加图书、删除图书和显示图书。构造器中,ioPerations
数组被初始化为一组操作对象,分别对应退出系统、查找图书、添加图书、删除图书和显示图书。menu()
方法用于展示管理员菜单,并接受用户的输入以确定执行哪项操作。
普通用户:
java
package user;
import operation.*;
import java.util.Scanner;
//普通用户
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
this.ioPerations=new IOPeration[]{
new ExitBook(),
new FindBook(),
new BorrowedBook(),
new ReturnBook()
};
}
@Override
public int menu() {
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("请输入你的操作:");
Scanner scanner=new Scanner(System.in);
int choice= scanner.nextInt();
return choice;
}
}
代码解释 :普通用户可以执行一些基本的操作,如查找图书、借阅图书、归还图书等。在构造方法中,
ioPerations
数组被初始化为一组操作对象,分别对应退出系统、查找图书、借阅图书和归还图书。menu()
方法用于展示普通用户的操作菜单,并接受用户输入,返回用户选择的操作。
5 .给图书管理员和普通用户的操作定义一个统一的操作接口,方便统一管理
java
package operation;
import book.Book;
import book.Booklist;
public interface IOPeration {
void work(Booklist books);
}
代码解释:work方法就是每个操作(删除,添加,显示,查找等)要实现的方法。
6 .之后就可以写一个实现这个图书管理系统的统一"入口"。
java
import book.Booklist;
import user.AdminUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
public class Main {
public static User login(){
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你的姓名:");
String name = scanner.nextLine();
System.out.println("请输入你的身份: 1.管理员 2.普通用户");
int choice=scanner.nextInt();
if(choice==1){
return new AdminUser(name);
}else {
return new NormalUser(name);
}
}
public static void main(String[] args) {
Booklist booklist=new Booklist();
User user=login();
while(true) {
int choice = user.menu();
user.doOperation(choice, booklist);
}
}
}
代码解释 :这段代码定义了一个
Main
类,作为程序的入口。首先,login()
方法负责登录功能,允许用户输入姓名和身份信息(管理员或普通用户)。根据用户的选择,login()
方法返回一个相应类型的用户对象(AdminUser
或NormalUser
)。在
main()
方法中,首先创建一个Booklist
对象,表示书架。然后调用login()
方法让用户登录并返回一个User
对象。接着,程序进入一个无限循环,每次循环调用user.menu()
展示用户操作菜单,获取用户的选择,然后通过user.doOperation()
执行相应的操作,传入当前的booklist
。
7.在实现了以上功能后,就有一定的雏形了:
接下来,把操作功能实现就行。
8 .显示图书。
java
import book.Book;
import book.Booklist;
public class ShowBook implements IOPeration{
@Override
public void work(Booklist booklist){
System.out.println("显示图书....");
int curSize=booklist.getUsedSize();
for (int i = 0; i <curSize ; i++) {
Book book=booklist.getBook(i);
System.out.println(book);
}
}
}
代码解释:对于显示图书,我们就传入一个书架对象,调用get方法获得书籍的有效个数,然后循环打印即可。
9 .归还图书。
java
package operation;
import book.Book;
import book.Booklist;
import java.util.Scanner;
public class ReturnBook implements IOPeration{
@Override
public void work(Booklist booklist) {
System.out.println("归还图书....");
System.out.println("请输入你要归还的图书:");
int curSize=booklist.getUsedSize();
Scanner scanner=new Scanner(System.in);
//输入要归还的图书
String name=scanner.nextLine();
//遍历书架,检查是否有这本书
for (int i = 0; i < curSize; i++) {
Book book=booklist.getBook(i);
//判断是否同名
if(book.getName().equals(name)){
//如果同名,再判断是否被归还
if(!book.isBorrowed()){
System.out.println("这本书没有被借阅,无需归还!!");
return;
}else {
System.out.println("成功归还"+name+"!");
book.setBorrowed(false);
}
return;
}
}
//书架没有这本书
System.out.println("书架中不存在你要归还的图书!!");
}
}
代码解释:(代码注解)。
10 .查找书籍。
java
package operation;
import book.Book;
import book.Booklist;
import java.util.Scanner;
public class FindBook implements IOPeration{
@Override
public void work(Booklist booklist){
System.out.println("查找图书....");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要查找的图书:");
String name=scanner.nextLine();
int curSize= booklist.getUsedSize();
for (int i = 0; i < curSize; i++) {
Book book=booklist.getBook(i);
if(book.getName().equals(name)){
System.out.println("找到你要找的图书了,图书信息如下:");
System.out.println(book);
return;
}
}
System.out.println("没有你要找的图书...");
}
}
代码解释 :通过一个标准输入流接收输入的name**(String name=scanner.nextLine();),然后再通过循环遍历,每本书的书名是否与输入的name相同(book.getName().equals(name))**,相同便打印该书的信息并返回,遍历结束说明,书架中没有这本书。
11 .退出系统。
java
package operation;
import book.Book;
import book.Booklist;
public class ExitBook implements IOPeration{
@Override
public void work(Booklist booklist) {
System.out.println("退出系统....");
int curSize= booklist.getUsedSize();
for (int i = 0; i < curSize; i++) {
booklist.setBook(i,null);
}
booklist.setUsedSize(0);
System.exit(0);//库函数
}
}
代码解释 :先是获取当前书籍列表的有效书籍数量
curSize,
遍历书籍列表,将每个位置的书籍对象设置为null
,清空书籍列表,然后将书籍列表的有效书籍数量设置为 0,最后调用System.exit(0)
方法终止程序。
12 .删除图书。
java
package operation;
import book.Book;
import book.Booklist;
import java.util.Scanner;
public class DelBook implements IOPeration{
@Override
public void work(Booklist booklist){
System.out.println("删除图书....");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要删除的图书的名称:");
String name=scanner.nextLine();
int curSize=booklist.getUsedSize();
int i = 0;
for (; i <curSize ; i++) {
Book book=booklist.getBook(i);
if(book.getName().equals(name)){
break;
}
}
//没有触发break
if(i>=curSize){
System.out.println("书架没有这本书,请重新输入!!");
return;
}
//触发break
for (int j=i;i<curSize;i++){
if(j==curSize-1)
booklist.setBooks(j,null);
else
booklist.setBooks(j,booklist.getBooks(i+1));
}
System.out.println("删除成功!");
}
}
代码解释:
遍历
booklist
中的所有书籍,查找匹配输入名称的图书。如果找到,跳出循环;如果没有找到,打印提示信息并返回。如果找到目标图书,从图书列表中删除该书。通过将后续图书前移 ,填补被删除图书的位置。
设置图书列表中最后一个位置为
null
(仅在图书列表中至少有一本书时)。
这里我们可以看一下触发break调用的方法:
13 .借阅书籍。
java
package operation;
import book.Book;
import book.Booklist;
import java.util.Scanner;
public class BorrowedBook implements IOPeration{
@Override
public void work(Booklist booklist) {
System.out.println("借阅图书....");
System.out.println("请输入你要借阅的图书:");
int curSize=booklist.getUsedSize();
Scanner scanner=new Scanner(System.in);
//输入要借阅的图书
String name=scanner.nextLine();
//遍历书架,检查是否有这本书
for (int i = 0; i < curSize; i++) {
Book book=booklist.getBook(i);
//判断是否同名
if(book.getName().equals(name)){
//如果同名,再判断是否被借阅
if(book.isBorrowed()){
System.out.println("这本书已经被借阅,请借阅其他图书!");
return;
}else {
System.out.println("成功借阅"+name+"!");
book.setBorrowed(true);
}
return;
}
}
//书架没有这本书
System.out.println("没有找到你要借阅的图书,请重新输入!");
}
}
代码解释:
(代码注解)。
14 .添加书籍。
java
package operation;
import book.Book;
import book.Booklist;
import java.util.Scanner;
public class AddBook implements IOPeration{
@Override
public void work(Booklist booklist){
if(isFull(booklist)){
System.out.println("书架满了,请扩容!");
//扩容(未写代码)
return;
}
System.out.println("新增图书....");
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();
scanner.nextLine();//避免回车被type读走,导致无法输入图书的类型
System.out.println("请输入该图书的类型:");
String type=scanner.nextLine();
Book book1=new Book(name,author,price,type);
int curSize=booklist.getUsedSize();
for (int i = 0; i <curSize ; i++) {
Book book=booklist.getBook(i);
if(book.getName().equals(name)){
System.out.println("图书馆已经存在该图书,请勿添加重复的图书!!");
return;
}
}
booklist.setBook(curSize,book1);
booklist.setUsedSize(curSize+1);
}
private boolean isFull(Booklist booklist){
return booklist.getBooks().length==booklist.getUsedSize();
}
}
代码解释:
检查书架是否已满 :调用
isFull
方法检查书架是否已满,如果满了,提示用户并终止操作。提示用户输入新图书信息 :依次提示用户输入图书名、作者、价格和类型,并使用
Scanner
获取用户输入。其中,为了防止nextInt()
后的回车符被nextLine()
读取,特意调用了一次scanner.nextLine()
。创建图书对象 :根据用户输入的数据,创建一个新的
Book
对象。检查图书是否已存在:遍历当前的书籍列表,检查是否已存在与输入图书名相同的书籍。如果存在,提示用户图书已存在,终止操作。
添加图书到书架 :将新的图书对象添加到
booklist
中的适当位置,并更新已使用的书籍数量。
对于标红字体:nextInt()
:nextInt()
只读取整数值,它会扫描输入直到遇到第一个非数字字符(如空格或换行符)时停止,但不会消耗这一行的换行符 。也就是说,nextInt()
会留下换行符在输入缓冲区中。如果省略
scanner.nextLine()
这一行,price
后面的换行符会留在缓冲区中,导致type = scanner.nextLine();
直接读取了这个换行符,用户不会有机会输入类型。