目录
operations(普通用户)
(ExitSys.java)
(FindBook.java)
(BorrowBook.java)
(ReturnBook.java)
operations(管理员用户)
(AddBook.java)
(DeleteBook.java)
主题:现在将要 写一个 能实现如同所示的功能的 图书管理系统
//结果图
思考 图中的功能实现 的思路
————————————————————————————————————
一个图书管理系统 包括 用户相关、图书相关 、菜单上操作相关,
为使分类方便,可以通过 使用package包 将各自相关类 在同一个包中组织
分为 Books包,Operations包,User包
根据结果图 思考后,实现图书管理系统大致分为以下几个步骤:
1.个人信息 + 身份 的确认
2.不同身份 和对应菜单 的调用
3.用户选择 和对应操作 的调用
4.实现各种 操作方法
一、选择不同身份
步骤1
步骤2
显示对应身份的菜单
创建 ‘管理员’ ‘普通用户’类,可以通过设置抽象类User, 提取两者重合的 成员和方法
此处User类中的方法menu不会被调用(抽象类不会直接实例化 ),所以menu可以设置为 抽象方法
(继承父类后,要调用父类构造方法 初始化父类成员)
(父类中的抽象方法,子类必须重写;否则子类必须也是抽象类)
在确定用户信息(1 2 )后,需要调用方法 打印对应用户的菜单,
q: 如何获取用户身份呢?
a: 登录过程封装,使用getter方法获取
q: 返回值类型应该是什么?
a: 用户身份不确定 是 Admin/Normal,可以用到父类User进行向上转型接收
q: 在设置完方法的返回类型后,在main函数调用时,发现依旧报错
a: main方法实际上 是静态方法,在静态方法中只能直接调用静态变量和方法,所以需要用static修饰login方法
------------------------------到此基本信息和页面已经完成
二:图书管理
现在进行 书 相关的内容(书类 ,将书组织起来的书架类 )
1. Book类
包括书属性的定义、成员的初始化,属性获取和设置的方法,重写toString方法
2. 书架 类
包括 所有书 和书的数量 以及 获取和设置方法
q: 将书架上设置几本初始的书,在显示图书时出现
a: 在书架的构造方法中设置,每次初始化都存在。并设置 当前本数
三、调用不同用户选择
思考:输入的choice和实际的操作如何对应起来
思路:通过数组将 其联系起来,能存放所有操作类的数组类型 只能是他们的父类或接口
(main)实现操作时,我们需要choice(菜单选择)和 shelf(操作的对象)完成调用对应操作的方法
(User.java)因为每次选择的对象不是确定的,所以 在父类中实现这个方法和创建各种操作的数字
(Normal.java) 因为Normal和Admin用户都 有不同的菜单操作
∴ 应该分别在两个用户的构造方法中进行初始化,必须给从父类 User 继承来的成员变量operations初始化,否则调用doIOperation访问operations[choice]就会出现NullPointerException。
//main函数下
BookShelf shelf = new BookShelf(); while(true){ int choice = user.menu(); user.doIoperation(choice,shelf); }//User.java
Ioperation[] operations ; public void doIoperation(int choice, BookShelf shelf) { operations[choice].work(shelf); }//Normal.java
public Normal(String name) { super( name); //此处的operations数字应该是 和User为同一个 this.operations = new Ioperation[]{ new ExitSys(), new FindBook(), new BorrowBook(), new ReturnBook() }; }
而这里的每个类都需要实现自己对应的操作,可以通过接口调用(也可以是抽象类,但是这里只需要一个方法被重写,所以 接口就能实现)
==========================================================
2.operations(普通用户)
具体的操作 需要通过实现不同的类 操作。在操作类中,可以通过接口 实现不同类中的方法,将不同操作练习起来
(ExitSys.java)
@Override public void work(BookShelf shelf) { System.out.println("退出系统"); System.exit(0); }(FindBook.java)
方法中将要查找的书 和书架上的书的书名 进行判断 是否一致
这里的比较的类型是String,是引用类型,要用equals方法比较,直接比较的是引用地址
注意:
1. shelf.getBooks().length获取的是书架能放的本数,而不是 现在已有的本数
2.//这种写法不安全,obj对象有可能是null,会抛出空指针异常。应该将 确定非空的对象作为 调用对象
public void work(BookShelf shelf) { System.out.println("请输入查询的书名"); Scanner scanner = new Scanner(System.in); String obj = scanner.nextLine(); //遍历书架上的书 进行条件判断 int len = shelf.getUsedSized();//1. shelf.getBooks().length❌for(int i = 0; i< len ; i++){ if(shelf.getBook(i).getName().equals(obj)){//2. if(obj.equals(shelf.getBook(i).getName()))❌不安全System.out.println("找到这本书了"); System.out.println(shelf.getBook(i)); return ; } } System.out.println("书架上没有这本书 "); }(BorrowBook.java)
进行图书状态的修改
public void work(BookShelf shelf) { System.out.println("请输入借阅的书名"); Scanner scanner = new Scanner(System.in); String obj = scanner.nextLine(); int len = shelf.getUsedSized(); for(int i = 0; i< len ; i++){ Book book = shelf.getBook(i); if(book.getName().equals(obj) ){ //先判断 当前这本书 是否借出 if(book.isState()){ System.out.println("这本书已经被借出"); return ; } book.setState(true); System.out.println("借阅成功"); System.out.println(book ); return ; } } System.out.println("借阅失败,书架上没有这本书 "); }(ReturnBook.java)
public void work(BookShelf shelf) { System.out.println("请输入归还的书名"); Scanner scanner = new Scanner(System.in); String obj = scanner.nextLine(); int len = shelf.getUsedSized(); for(int i = 0; i< len ; i++){ Book book = shelf.getBook(i); if(book.getName().equals(obj) ){ if(!book.isState()){ System.out.println("这本书并未借出,无需归还!"); return; } book.setState(false); System.out.println("归还成功"); System.out.println(book); return ; } } System.out.println("归还失败,书架上没有这本书 "); }//==============================
operations(管理员用户)
(AddBook.java)
注意:
nextInt()只会读取数字,不会读取按下回车产生的换行符\n回车换行残留在输入缓冲区里,
后面的nextLine()一读到这个换行,直接判定输入结束,跳过了你的输入机会。
所以这两个的顺序不能变(或者 在nextInt后添加一行nextLine 消除掉换行 )
public void work(BookShelf shelf) { //1.判断 是否能放下书 int len = shelf.getUsedSize(); if(len== shelf.getBooks().length){ System.out.println("书架已满,无法添加新书"); return ; } //2.输入新书的信息 Scanner scanner = new Scanner(System.in); System.out.println("请输入添加图书的书名"); String name = scanner.nextLine(); System.out.println("请输入添加图书的作者"); String author = scanner.nextLine(); System.out.println("请输入添加图书的类型");String type = scanner.nextLine(); //⭐System.out.println("请输入添加图书的价格");int price = scanner.nextInt();Book newone = new Book(name,author,price,type); System.out.println(newone); //3.书架上是否有相同的书 for(int i = 0; i<len ;i++){ Book bookF = shelf.getBook(i); if(bookF.getName().equals(name)){ System.out.println("书架上已经有这本书了,添加失败"); return ; } } //4.添加图书 shelf.setBook(newone ,len); System.out.println("成功添加图书"); shelf.setUsedSize(len+1); }(DeleteBook.java)
删除图书,将该图书后的向前覆盖即可
public void work(BookShelf shelf) { System.out.println("请输入删除图书的名称"); Scanner scanner = new Scanner(System.in); String obj = scanner.nextLine(); //1. 寻找图书 int len = shelf.getUsedSize(); int pos =-1; int i = 0; for(; i<len ;i++){ String hasBook = shelf.getBook(i).getName(); if(hasBook.equals(obj)){ pos=i; System.out.println("找到这本书了"); break; } } if(pos==len){ System.out.println("书架上没有这本书,删除失败"); return; } //2. 删除图书 for(int j = pos ;j< len-1;j++){ Book book = shelf.getBook(j+1); shelf.setBook(book,j); } shelf.setBook(null,len-1); shelf.setUsedSize(len-1); System.out.println("删除成功"); }