在开始前就应该想好,这个图书馆实现的功能是什么,里面会有哪些具体的方法,以及如何利用面向对象,多态等思想去构造这个系统
面向对象,如何将这个图书管理系统给抽象出来是我们需要解决的。
居然是图书管理系统,那么里面就一定有图书,类似于c语言通讯录,进而就是对这些图书的增删查改等操作。对于这么一个面向对象的人机交互系统,那么必然存在一个管理员来完成这些查改操作,此外对于用户来说,这个系统应该有借阅,显示书籍是否被借阅,归还书籍的功能等。
1、定义图书
定义单个书本,我们定义书籍类:
package book; public class Book { // 书籍属性 private String name; // 书名 private int indext; // 书籍索引 private String author; // 作者 private int price; // 价格 private String type; // 类型 private boolean state; // 构造方法,设置初始化书名,书记索引,作者,价格,类型 public Book(String name, int indext, String author, int price, String type) { this.name = name; this.indext = indext; this.author = author; this.price = price; this.type = type; } 提供get和set方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getIndext() { return indext; } public void setIndext(int indext) { this.indext = indext; } 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 isState() { return state; } public void setState(boolean state) { this.state = state; } // 重写toString方法,打印某一个书籍的完整信息 @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", indext=" + indext + ", author='" + author + '\'' + ", price=" + price + ", type='" + type + '\'' + ", state=" + state + '}'; } }
里面有书名,作者 ,索引,类型,价格,和是否被借阅等参数。(由于在类中,boolean类型初始化默认为false,也就是未被借出,所以在构造方法里面可以不对state进行构造)
为了数据安全,将这些属性设置为private修饰的变量,所以提供get和set方法,让我们能对这些属性做出一些修改或者获取这个书本的属性。
我们一本一本的书构成一个书籍的集合,我们可以用数组来表示,在这个数组外面,还应该有用来表示已存的书籍的个数的变量,此外还应该有获取和修改这些成员变量的方法。例如获取书籍的数量,获取里面某个书籍的引用以操作这个书籍。
将这些变量和方法整理为一个booklist类。
package book; import MyError.checkGetPos; import MyError.checkIsFull; public class BookList { 成员变量 private Book[] books = new Book[10]; private int usedSize = 0; private void checkGetPos(int pos){ if(pos < 0 || pos >= this.usedSize ){ throw new checkGetPos("pos in check is not allowed"); } } private void checkBookIsFull(){ if( this.usedSize > 10){ throw new checkIsFull("the booklist is full!"); } } 成员方法 public Book getBook(int pos){ // 获取某本书 try { checkGetPos(pos); }catch (checkGetPos e){ e.printStackTrace(); } return books[pos]; } // 存放某本书 public void pushIn(Book newBook){ checkBookIsFull(); this.books[this.usedSize] = newBook; } public int getUsedSize(){ // 获取当前书籍存放数量 return usedSize; } public void setUsedSize(int usedSize){ //设置当前的书籍存放数量 this.usedSize = usedSize; } public boolean isFull(int pos){ //判断数据某个pos位置是否存在书籍 checkGetPos(pos); return books[pos] != null; } public boolean isEmpty(){ //判断书籍数组是否为空 return usedSize == 0; } /// 构造方法 public BookList(){ } // }
然后将单个书籍book类和书籍列表booklist类放入一个Book Package包当中
管理员
对于管理员,应该具有以下功能:
首先将管理员定义为一个admin类:
import java.util.Scanner; public class AdminUser{ public int menu(){ System.out.println("==========="); System.out.println("1.查找图书"); System.out.println("2.新增图书"); System.out.println("3.删除图书"); System.out.println("4.显示图书"); System.out.println("5.修改图书"); System.out.println("0.退出系统"); System.out.println("==========="); System.out.println("请输入您想要的操作:(1,2,3,4,5,0)"); Scanner scanf = new Scanner(System.in); return scanf.nextInt(); } }
我们逐个实现。
创建一个operate Package包来存放这些操作的类。
这些操作都是用来操作这个booklist类里面的成员变量,他们里面都有操作booklist这个方法,所以我们将其抽象为一个接口 Ioperate,将这个接口和增删查改都放入一个operate Package包。
Ioperate:
package Operate; import book.BookList; public interface Ioperate { void work(BookList bookList); }
然后在 具体的增删查改中重写这个work方法即可
Add:
增添图书
package Operate; import book.Book; import book.BookList; import java.util.Scanner; public class Add implements Ioperate{ public void work (BookList bookList){ System.out.println("Add book!"); Scanner scan = new Scanner(System.in); System.out.println("请输入书籍名"); String name = scan.nextLine(); int count = bookList.getUsedSize(); for(int i = 0; i < count ;i++){ Book tem = bookList.getBook(i); if (tem.getName().equals(name)){ System.out.println("han been there!!"); return; } } System.out.println("请输入书籍作者名"); String author = scan.nextLine(); System.out.println("请输入书籍价格"); int price = scan.nextInt(); System.out.println("请输入书籍类型"); String type = scan.nextLine(); Book book = new Book(name, author, price, type); // 由于book数据用private修饰,所以需要使用booklist内的方法来放入图书 bookList.pushIn( book ); bookList.setUsedSize(count+1); } }
Find:
查找图书(按书籍名)
package Operate; import book.Book; import book.BookList; import java.util.Scanner; public class Find implements Ioperate{ public void work(BookList bookList){ System.out.println("查找图书\n"); System.out.println("请输入书名"); Scanner scan = new Scanner(System.in); String TheName = scan.nextLine(); int count = bookList.getUsedSize(); for (int i = 0; i < count; i++) { Book book = bookList.getBook(i); if( book.getName().equals(TheName)){ System.out.println(book); System.out.println("书籍索引index为"+book.getIndext()); return; } } System.out.println("没有这本书!!请联系管理员"); } }
查找书籍即遍历整个book数组。配合booklist当中的getBook方法。
delete:
删除图书,按书籍名
package Operate; import book.Book; import book.BookList; import java.util.Scanner; public class Delete implements Ioperate{ @Override public void work(BookList bookList) { System.out.println("删除图书"); while(true){ System.out.println("请输入您要输入的图书的名字,或者输入数字0以退出删除并回到上一步"); Scanner scan = new Scanner(System.in); String name = scan.nextLine(); if (name.equals("0")) { return; } int count = bookList.getUsedSize(); int flag = -1; for (int i = 0; i < count; i++) { Book book = bookList.getBook(i); if( book.getName().equals(name)){ System.out.println(book); flag = i; } } if (flag == -1) { System.out.println("没有此书,删除错误"); break; } for (int i = flag; i < count-1; i++) { Book book = bookList.getBook(i+1); bookList.pushInPos(i,book); } bookList.pushInPos(count - 1 ,null); bookList.setUsedSize(count-1); } } }
show
显示图书
即遍历数组然后打印:
package Operate; import book.Book; import book.BookList; public class Show implements Ioperate{ @Override public void work(BookList bookList) { System.out.println("打印所有图书!"); int count = bookList.getUsedSize(); for(int i = 0; i < count ;i++){ Book book = bookList.getBook(i); System.out.println(book); } System.out.println("共有 "+bookList.getUsedSize()+" 本图书"); } }
5、modify
修改图书:
package Operate; import book.Book; import book.BookList; import java.util.Scanner; public class Modify implements Ioperate{ public String checkIsEnd(){ Scanner in = new Scanner(System.in); return in.nextLine(); } @Override public void work(BookList bookList) { System.out.println("Modify the data"); System.out.println("请输入您想要修改书籍的书籍名"); Scanner in = new Scanner(System.in); String bookName = in.nextLine(); int count = bookList.getUsedSize(); int flag = -1; for (int i = 0; i < count; i++) { Book book = bookList.getBook(i); if( book.getName().equals(bookName)){ System.out.println(book); flag = i; } } if (flag == -1) { System.out.println("没有此书,删除错误"); return; } Book book = bookList.getBook(flag); System.out.println("请重新输入其参数,如果不需要修改则中途可以输入0退出,但是之前修改的数据会被保存"); System.out.println("请修改书籍名"); String newName = in.nextLine(); if( newName.equals("0")){ System.out.println("正在退出!"); return; } book.setName(newName); System.out.println("请修改作者!"); String author= in.nextLine(); if( author.equals("0")){ System.out.println("正在退出!"); return; } System.out.println("请修改价格!"); int price = in.nextInt(); if( price == 0 ){ System.out.println("正在退出!"); return; } System.out.println("请修改类型!"); String type= in.nextLine(); if( type.equals("0")){ System.out.println("正在退出!"); return; } System.out.println("请修改在馆情况!"); String state= in.nextLine(); if( state.equals("0")){ System.out.println("正在退出!"); return; } //调用fori ---->>> Book book = booklist.getBook(i) ---->>> book.set --->>>修改成功 // } }
里面仍然有很多可以简化的地方,但是这里为了可读性就不在此展示。
用户
对于用户,应该具有以下功能:
查找图书和管理员相同,这里可以不用再重复写一次
borrow:
借阅图书:
package Operate; import book.Book; import book.BookList; import java.util.Scanner; public class Borrow implements Ioperate{ @Override public void work(BookList bookList) { System.out.println("借阅图书"); while(true){ System.out.println("请输入你要借阅的书籍的书名:"); System.out.println("或者输入数字0以退出!"); Scanner scan = new Scanner(System.in); String name = scan.nextLine(); if (name.equals("0")) { return; } int count = bookList.getUsedSize(); for (int i = 0; i < count; i++) { Book book = bookList.getBook(i); if (book.getName().equals(name) && book.isState()){ // fasle 不在馆 book.setState(false); System.out.println("借阅成功"); return; } } } } }
return:
归还图书
package Operate; import book.Book; import book.BookList; import java.util.Scanner; public class Return implements Ioperate{ @Override public void work(BookList bookList) { System.out.println("归还图书"); while(true){ System.out.println("请输入你要归还的书籍的书名:"); System.out.println("或者输入数字0以退出!"); Scanner scan = new Scanner(System.in); String name = scan.nextLine(); if (name.equals("0")) { return; } int count = bookList.getUsedSize(); for (int i = 0; i < count; i++) { Book book = bookList.getBook(i); if (book.getName().equals(name) && !book.isState()){ // 0 设置为 已经借出 1设置为在馆 book.setState(true); System.out.println("归还成功"); return; } } } } }
exit
退出系统
package Operate; import book.BookList; public class ExitSystem implements Ioperate{ @Override public void work(BookList bookList) { System.out.println("退出系统"); } }
组装
剩下的就是对管理员和用户进行抽取,来设置一个父类user,里面具有user的name属性,同时里面必须具备对于用户或者是管理员的操作方法,在user父类里面定义一个数组来存放这些操作类,然后在不同的身份情况下,实例化不同的操作方法:
user类
package Users; import book.BookList; import Operate.Ioperate; public abstract class User { protected String name; protected Ioperate[] ioperates; public User(String name){ this.name=name; } public abstract int menu(); public void dowork(int choice, BookList bookList){ this.ioperates[choice].work(bookList); } }
用户:
package Users; import Operate.*; import java.util.Scanner; public class NomalUser extends User{ public NomalUser(String name) { super(name); this.ioperates = new Ioperate[]{ new ExitSystem(),new Find(),new Borrow(),new Return() }; } public int menu(){ System.out.println("hello " + name+" !Welcome to this libarary system"); 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("请输入您想要的操作:(1,2,3,0)"); Scanner scanf = new Scanner(System.in); return scanf.nextInt(); } }
管理员
package Users; import Operate.*; import java.util.Scanner; public class AdminUser extends User{ public AdminUser(String name){ super(name); this.ioperates = new Ioperate[]{ new ExitSystem(),new Find(),new Add(),new Delete(),new Show(),new Modify() }; } public int menu(){ System.out.println("hello " + name+" !Welcome to this libarary system"); System.out.println("==========="); System.out.println("1.查找图书"); System.out.println("2.新增图书"); System.out.println("3.删除图书"); System.out.println("4.显示图书"); System.out.println("5.修改图书"); System.out.println("0.退出系统"); System.out.println("==========="); System.out.println("请输入您想要的操作:(1,2,3,4,5,0)"); Scanner scanf = new Scanner(System.in); return scanf.nextInt(); } } 2.
接下来就是主函数的逻辑书写:
这里可以根据情况进行书写:
main方法
import book.BookList; import Users.AdminUser; import Users.NomalUser; import Users.User; import java.util.Scanner; public class Main { public static User login(){ System.out.println("请输入你的姓名:"); Scanner scanf = new Scanner(System.in); String name = scanf.nextLine(); System.out.println("请输入您的身份:1.用户 2.管理员"); System.out.println("或输入数字 0 以退出系统!"); int choice = scanf.nextInt(); if (choice == 2){ return new AdminUser(name); }else if(choice == 1){ return new NomalUser(name); }else { return null; } } public static void main(String[] args) { BookList bookList =new BookList(); while(true) { User user = login(); if(user == null){ System.out.println("成功退出!"); break; } while(true){ int choice = user.menu(); user.dowork(choice,bookList); if (choice == 0) { break; } } } // 根据user的类型和 flag 来确定 调用哪个对象的哪个部分 } }