目录
一、图书管理系统展示
1.管理员
2.普通用户
编辑3.操作
二、图书管理系统基本实现思路
book --- 包
1.Book类
注意:
2.BookList类
注意:
Opreration --- 包
Operration接口
1.AddOperation -- 增加图书
注意:
2. BorrowOperation -- 借阅图书
3.DeletOperation -- 删除图书
注意:
4.DisplayOperation -- 展示图书
5.Exit -- 退出系统
6.FindOperation -- 查找图书
7.ReturnOperation -- 归还图书
User --- 包
User -- 父类
1.Admin -- 管理员
注意:
2.Normal -- 普通用户
Main -- 主函数
注意:
三、总结
首先给大家展示以下图书管理系统最终的效果,我们再下面的文章里再细讲每个部分及功能的具体实现,先输入你的名字进入系统,接着再选择你的身份。
针对每个身份有每个身份不一样的操作
管理员的操作包括增加图书,删除图书,查找图书,展示图书和推出系统。
普通用户的操作包括查找图书,借阅图书,展示图书,归还图书和退出系统。
--书的设计图,用来创建每一本图书对象。
书的属性包括——>书名,书的作者,价格,书的类型 以及有没有被借出
1.这里isBorrow初始化为 flase 未被借出
2.需要重写toString方法
3.私有成员变量需要写出 getter 和 setter方法来访问
package book;
//书类
public class Book {
//书名 作者 价格 书的类型 有没有被借出
private String name;
private String author;
private double price;
private String type;
//是否被借出 ture为借出
private boolean isBorrow;
//有参构造器 有没有被借出是需要后续判断的,不需要初始化,boolean类型初始化为false
public Book(String name, String author, double price, String type){
this.name = name;
this.author = author;
this.price = price;
this.type = type;
}
//因为是私有成员变量,所以需要getter 和 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 String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isBorrow() {
return isBorrow;
}
public void setBorrow(boolean borrow) {
isBorrow = borrow;
}
//重写toString方法
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
", isBorrow=" + isBorrow +
'}';
}
}
--用来存放图书,相当于一个书架,一个存放图书的数组这是一个简单系统,我们给它初始化三本书
在书架类里设定几个我们需要用到的方法,方便功能的操作
1.给一个下标,返回这个下标对应的图书
2.给定一个下标,在这个位置放置一本图书
3.获取当前有多少本书
4.修改图书的本数,为增加、删除图书做准备
1.我们需要设定一个变量来实时记录当前这个数组里有几本书,方便功能的操作
package book;
import java.util.ArrayList;
//书架,放书的数组
public class BookList {
//书架存放10本书
private Book[] Books= new Book[10];
//记录当前书的数量
private int BookSize ;
//在构造器里初始化三本书
public BookList() {
Books[0] = new Book("三国演义","罗贯中",39.9,"小说");
Books[1] = new Book("西游记","吴承恩",45.5,"小说");
Books[2] = new Book("JAVA编程","青",68.9,"知识");
BookSize = 3;
}
/**
* 返回下标为pos 的一本书
* @param pos 下标
* @return 一本书
*/
public Book getBooks(int pos) {
return Books[pos];
}
/**
* 在pos位置放一本书
* @param pos 下标位置
* @param book 一本书
*/
public void setBooks(int pos,Book book) {
Books[pos] = book;
}
/**
* 实时获取当前书有多少本
* @return
*/
public int getBookSize() {
return BookSize;
}
/**
* 修改书架中书的本数
*/
public void setBookSize(int size) {
BookSize = size;
}
}
这是一个接口规范,因为增加图书,删除图书..这些操作都可以遵循这个规范,所以我们定义一个接口,在具体写每一个操作时,实现这个接口,在接口写一个抽象方法,在每一个操作类里,重写这个抽象方法即可
注意:这个接口里方法的参数是书架,所以我们接下来的操作都是对这个书架进行操作
package Operation;
import book.BookList;
//接口规范 这几个实现类都是操作数组的,写成接口
public interface Operration {
public abstract void work(BookList bookList);
}
实现Operation接口
1.增加图书时,需要先判断书架是否已经放满,在没有放满的情况下,才能增加图书
2.增加图书后,一定要记得修改当前书架中图书的本数
package Operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
/**
* 增加图书
* 实现接口
*/
public class AddOperation implements Operration{
@Override
public void work(BookList bookList) {
System.out.println("===========新增图书功能=========");
System.out.println();
//判断书架是否已经满了
if(bookList.getBookSize() == 10){
System.out.println("书架已经满了,放不下了~");
return;
}
System.out.println("请输入书名");
Scanner in= new Scanner(System.in);
//nextLine()是 接受回车之前的所有字符包括空格
//next()如果输入有空格,自动断掉
String name = in.nextLine();
System.out.println("请输入作者的名称");
String author = in.nextLine();
System.out.println("请输入书本的价格");
double price = in.nextDouble();
System.out.println("请输入书本的类型");
String type = in.nextLine();
System.out.println("==============");
//创建一本新的书,将以上属性放进去
Book book = new Book(name,author,price,type);
int ret = bookList.getBookSize();
bookList.setBooks(ret,book);
bookList.setBookSize(ret + 1);
System.out.println("新增书籍成功!");
}
}
通过书名,遍历书架,首先查找在书架中查找有没有用户想要借阅的图书,如果有再通过Book类中的isBrrow是否为flase,如果为true,则说明要借阅的这本书已经被借出。
package Operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowOperation implements Operration{
@Override
public void work(BookList bookList) {
System.out.println("=========借阅图书==========");
System.out.println();
System.out.println("请输入你要借阅的书籍的名字:");
Scanner in = new Scanner(System.in);
String name = in.nextLine();
for (int i = 0; i < bookList.getBookSize(); i++) {
Book book = bookList.getBooks(i);
if(book.getName().equals(name)){
if(book.isBorrow() == true){
System.out.println("不好意思,你要找到你这本书已经被借出去了");
return;
}else{
System.out.println("借阅成功!");
book.setBorrow(true);
return;
}
}
}
System.out.println("没有你要找的书!");
}
}
通过书名找到这本书,再从对应的下标位置往后,依次向前挪一位,覆盖需要删除的部分,但是我这个代码细心的同学可能会发现一个问题,就是i+1,当我的数组存放的书是满的时候,i+1就越界了,有其他想法的同学可以在评论区告诉我
1.删除图书后,记得将当前图书中的书本数量减1
package Operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class DeletOperation implements Operration{
@Override
public void work(BookList bookList) {
System.out.println("===========删除图书==========");
System.out.println();
System.out.println("请输入你要删除的图书的名字!");
Scanner in = new Scanner(System.in);
String name = in.nextLine();
for (int i = 0; i < bookList.getBookSize(); i++) {
Book book = bookList.getBooks(i);
//如果名字相同,删除,再把后面的依次挪上来
if(book.getName().equals(name)){
//把这本书的下标取出来 i对应下标
if(i == bookList.getBookSize()-1){
}
for (int j = 0; j < bookList.getBookSize() - i; j++) {
bookList.setBooks(i,bookList.getBooks(i+1));
}
System.out.println("删除成功!");
bookList.setBookSize(bookList.getBookSize() - 1);
return;
}
}
System.out.println("没有你要删除的书名!");
}
}
遍历一遍数组,将数组中的书展示出来
package Operation;
import book.Book;
import book.BookList;
public class DisplayOperation implements Operration{
@Override
public void work(BookList bookList) {
System.out.println("==========展示图书===========");
System.out.println();
int size = bookList.getBookSize();
for (int i = 0; i < size; i++) {
Book book = bookList.getBooks(i);
System.out.println(book);
}
System.out.println();
}
}
System.exit(0)
package Operation;
import book.BookList;
public class Exit implements Operration{
@Override
public void work(BookList bookList) {
System.out.println("===========退出系统============");
System.exit(0);
}
}
通过书名来查找图书对象,遍历数组,当数组中存放的书名与想要查找的书名一致时,打印出来
package Operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class FindOperation implements Operration{
@Override
public void work(BookList bookList) {
System.out.println("==========查找图书===========");
System.out.println();
int size = bookList.getBookSize();
System.out.println("请输入图书的名字!");
Scanner in = new Scanner(System.in);
String name = in.nextLine();
//查找功能
for (int i = 0; i < size; i++) {
Book book = bookList.getBooks(i);
if(book.getName().equals(name)){
System.out.println("找到了这本书");
System.out.println(book);
return;
}
}
//没找到
System.out.println("找不到你想要找的这本书!");
}
}
遍历数组中的书,找到与其相同的名字,归还就是改掉他的借阅状态
注意:归还成功,一定要改书本的借阅状态
package Operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class ReturnOperation implements Operration{
@Override
public void work(BookList bookList) {
System.out.println("=========归还图书==========");
System.out.println();
System.out.println("请输入归还书的名字!");
Scanner in = new Scanner(System.in);
String name = in.nextLine();
for (int i = 0; i < bookList.getBookSize(); i++) {
Book book = bookList.getBooks(i);
if(book.getName().equals(name)){
book.setBorrow(false);
System.out.println("归还成功!");
return;
}
}
System.out.println("没找到你归还的书!");
}
}
1.首先思考管理员和普通用户都是人,那么我们是不是可以将他写成一个父类,在用两个子类来继承这个父类
2.我们要在两个身份中写出不同的两个的菜单,因为针对每个身份有每个身份不一样的操作。
1.在父类中,定义了一个接口数组,这个数组中可以放上述中对图书的增删查改操作
2.这里的这个数组没有进行初始化也没有分配大小,再子类中分配,因为每个子类的操作方法不同,所以我们这里只需要定义一个即可
3.普通用户和管理员都需要菜单,但是菜单实现的也不同,所以将父类中的菜单定义成一个抽象方法,在子类中进行重写
package User;
import Operation.Operration;
import book.BookList;
public abstract class User {
//人都有名字
protected String name;
//管理员和普通用户的操作是不一样的,比如管理员的2操作是删除图书,普通用户是借阅图书
//定义一个接口数组 因为new的对象不一样,所以准备的操作是不一样的
protected Operration[] operrations; //这里并没有初始化也,没有分配大小,再子类中分配
public User(String name) {
this.name = name;
}
public abstract int menu();
public void doOperation(int choice, BookList bookList) {
this.operrations[choice].work(bookList);
}
}
1.在父类有有参构造器,所以我们在写子类的时候,必须帮助父类构造
2.我们这里的菜单让他返回一个整数,表示用户选择的操作,然后在主函数中进行操作
3.在子类中,我们需要对操作数组进行初始化,需要哪些操作就将那些操作放进这个数组中
4.我们可以将数组0下标设置为退出系统,更好的对应菜单
0 1 2 3 4
package User;
import Operation.*;
import book.BookList;
import java.util.Scanner;
//图书管理人员
//继承 User类
public class Admin extends User{
因为父类有有参构造器,必须super帮助父类构造
public Admin(String name){
super(name);
//分配定义的操作数组大小和内容
this.operrations = new Operration[5];
operrations[1] = new AddOperation();
operrations[2] = new DeletOperation();
operrations[3] = new FindOperation();
operrations[4] = new DisplayOperation();
operrations[0] = new Exit();
}
//重写menu抽象方法
@Override
public int menu() {
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("0.退出系统");
Scanner in = new Scanner(System.in);
System.out.println("请选择你的操作:");
int choise = in.nextInt();
return choise;
}
}
和管理员类似
package User;
import Operation.*;
import java.util.Scanner;
//借书的人
//继承 User父类
public class Normal extends User{
//因为父类有有参构造器,必须super帮助父类构造
public Normal(String name) {
super(name);
//分配定义的操作数组大小和内容
this.operrations = new Operration[5];
operrations[0] = new Exit();
operrations[1] = new FindOperation();
operrations[2] = new BorrowOperation();
operrations[3] = new DisplayOperation();
operrations[4] = new ReturnOperation();
}
重写menu抽象方法
@Override
public int menu() {
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("0.退出系统");
Scanner in = new Scanner(System.in);
System.out.println("请选择你的操作:");
int choise = in.nextInt();
return choise;
}
}
在Main类里,我们还需要写一个登录操作,判断输入的用户是管理员还是普通用户,在主函数中调用登录方法,这个登录方法返回的是一个对象,返回管理员对象或者普通用户对象,在主函数中,我们需要接这个对象
首先我们new一个书架,初始化三本图书
1.登录方法返回的对象可能是管理员,也有可能是普通用户,所以在接这个对象的时候,我们用User这个父类来接
import User.Admin;
import User.Normal;
import User.User;
import book.BookList;
import java.util.Scanner;
public class Main {
/**
* 登录方法
* @return 返回一个人对象,User为父类,发生向上转型,多态
*/
public static User login(){
System.out.println("请输入你的姓名:");
Scanner in = new Scanner(System.in);
String name = in.nextLine();
System.out.println("你的身份是:1.管理员 2.普通用户");
int ret = in.nextInt();
if(ret == 1){
//管理员
return new Admin(name);
}else{
//普通用户
return new Normal(name);
}
}
public static void main(String[] args) {
//new一个书架,准备图书
BookList bookList = new BookList(); //初始化了三本书
//登录 这个返回的user不确定是管理人员还是普通用户
User user = login();
while (true) {
int choice = user.menu();//动态绑定
user.doOperation(choice,bookList);
}
}
}
这里的user.meu实现的多态中的动态绑定,user会根据自己的类型找到对应的菜单,从而进行调用
这是写在User父类里的方法,写在父类里的原因是因为我们登录方法中返回的对象是用user这个父类来接的
到这儿,这个简单的图书管理系统就介绍完了,这个系统只是一个模拟,还有很多方面需要改进,需要学习新的东西,对于这个代码来说,我们重点需要掌握的是,整个代码的框架,每个功能代码基本都是类似的,只要掌握代码框架和逻辑,这对你来说也不会很难,看到这儿,如果你有什么疑问或者改进,欢迎评论。