一.抽象出对象:
1.要有书架,图书,用户(包括普通用户,管理员用户)。根据这些我们可以建立几个包,来把繁杂的代码分开,再通过一个类来把这些,对象整合起来实现系统。说到整合,肯定缺不了,相关接口,我们再定义一个,放接口,和扩展这个接口的方法。
如图:
二.构思:
1.先在书架类上,初始化好默认书籍,其他构造方法(如:getBook,setBook(在具体的下标,放书和返回书)),具体,在写实现接口的方法时,来增加。
public class BookList {
//组合的方式,初始化书架
private Book[] books = new Book[10];
private int usedSize;//实际放的,书的个数
//初始化书架(放书)
public BookList() {
this.books[0] = new Book("三国演义", "罗贯中", 12, "小说");
this.books[1] = new Book("红楼梦", "曹雪芹", 13, "小说");
this.books[2] = new Book("西游记", "吴承恩", 14, "小说");
this.usedSize = 3;
}
//返回一本,pos(要找的书)下标的书
public Book getBook(int pos) {
return books[pos];
}
//插入一本书的方法(相当于,要初始化好,书架原来已有的书)
public void setBook(int pos, Book books) {
this.books[pos] = books;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public Book[] getBooks() {
return books;
}
public void setBooks(Book[] books) {
this.books = books;
}
}
2.在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*/
'}';
}
}
3.在User类中,定义好name和,相关构造方法,以及接口命名的数组,为后面,到达调用,扩展了接口的类,里的方法,做铺垫。
public abstract class User {
protected String name;
//定义,接口命名,类型的数组,后续配合,
// 【return new AdminUser(name);】就可以看出,再加上接口调用的方法,就知道,操作了哪一个方法
protected IOperation[] iOperations;
//要根据子类,来初始化,父类成员变量
public User(String name) {
this.name = name;
}
public abstract int menu();
//这里封装一个方法,提供给,Main调用。
public void DoIOperation(int choice, BookList bookList) {
//这里,iOperations数组,里有我们要的对象,通过,数组里的对象,调用接口里的方法
iOperations[choice].work(bookList);
}
}
4.管理员类中(AdminUser)和普通用户类中(NormalUser)继承了user类,初始化好系统菜单,相关构造方法。(这个构造方法很关键,用接口作为,数组相当于实例化了,扩展了接口的类,的方法,达到调用系统具体方法的作用 )
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
//通过【return new AdminUser(name);】,再加上实现接口的方法,就知道,操作了哪一个方法
//登录界面,选择了哪个,角色(NormalUser)或者(AdminUser),this就是哪个的引用
this.iOperations = new IOperation[] {
//这些对象都实现了,iOperations接口,所以不会报错
//下面相当于实例化了,扩展了接口的类,的方法,达到调用系统具体方法的作用
new ExitOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation(),
};
}
public int menu() {
System.out.println("欢迎" + this.name + "使用图书系统");
System.out.println("********普通用户菜单********");
System.out.println("1. 查找图书");
System.out.println("2. 借阅图书");
System.out.println("3. 归还图书");
System.out.println("0. 退出系统");
System.out.println("*************************");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你的操作:");
int choice = scanner.nextInt();
return choice;
}
}
5.在Main类中写好,登录界面,及整合一下,如何实例化对象,来操作系统。
public static void main(String[] args) {
//实例化书架
BookList bookList = new BookList();
//通过返回值,向上转型,确定用户
//这里的user是,返回的(AdminUser),或者(NormalUser)
User user = login();
while (true) {
//然后,通过返回信息,调用恰当的菜单
int choice = user.menu();//发生了,动态绑定
/**
* 根据choice,返回值看看,调用了哪个方法
*
* 1.哪个对象?
* 答:User user = login();
*
* 2.哪个方法?-》进一步,还要确定,当前对象,包含了这些方法
*答:在构造方法【return new AdminUser(name)】运行时,会初始化好,对应的操作对象。
*
* 注意:后面通过父类对象,调用方法,(int choice = user.menu();),通过choice判断
* 调用了,哪个方法 ,接下来就要对,父类,进行操作
*/
user.DoIOperation(choice, bookList);
}
}
}
6.初始化好,接口和,菜单里操作系统的work方法(实现了这个接口的,类就是,每个操作系统的方法)
public interface IOperation {
//这个接口,有操作书架的方法,在其他类实现,就可以,操作性的区分,不同用户的方法
public void work(BookList bookList);
}
7.接下来就是实现了,接口的每一个类(每个操作系统的方法)
以下是管理员菜单方法:
(1).查找图书:
public class FindOperation implements IOperation {
@Override
public void work(BookList bookList) {
System.out.println("查找图书");
int currentSize = bookList.getUsedSize();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要查找的图书");
String name = scanner.nextLine();
for (int i = 0; i < currentSize; i++) {
//遍历,书架,已初始化的书
Book book = bookList.getBook(i);
if (book.getName().equals(name)) {
System.out.println("找到了");
System.out.println(book);
return;
}
}
System.out.println("没有你要找的书...");
}
}
(2).新增图书:
public class AddOperation implements IOperation{
@Override
public void work(BookList bookList) {
//1.判断书架(数组)是否满了
int currentSize = bookList.getUsedSize();
if (currentSize == bookList.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("请输入新增的价格");
int price = scanner.nextInt();
System.out.println("请输入新增的类型");
String type = scanner.next();
Book newBook = new Book(name, author, price, type);
//3.判断书架是否,已经存在这本书
for (int i = 0; i < currentSize; i++) {
//遍历,书架,已初始化的书
Book book = bookList.getBook(i);
if (book.getName().equals(name)) {
System.out.println("书已经存在了,不用再添加了");
return;
}
}
//插入图书
bookList.setBook(currentSize, newBook);
bookList.setUsedSize(currentSize+1);
}
}
(3).删除图书:
public class DelOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("删除图书");
int currentSize = bookList.getUsedSize();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要删除的图书");
String name = scanner.nextLine();
int pos = 0;
int i = 0;
for (; i < currentSize; i++) {
//遍历,书架,已初始化的书
Book book = bookList.getBook(i);
if (book.getName().equals(name)) {
//找到要删除的,位置
pos = i;
break;
}
}
if (i == currentSize) {
System.out.println("没有找到你要删除的图书");
}
//开始删除
for (int j = pos; j < currentSize-1; j++) {
//思路:bookList[j] = bookList[j+1];
//先找到j+1,那个位置,然后覆盖
Book book = bookList.getBook(j+1);
bookList.setBook(j, book);
}
//更新下标
bookList.setUsedSize(currentSize-1);
System.out.println("删除成功");
}
}
(4).显示图书:
public class ShowOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("显示图书");
int currentSize = bookList.getUsedSize();
for (int i = 0; i < currentSize; i++) {
//遍历下标,把找到的图书打印出来
Book book = bookList.getBook(i);
System.out.println(book);
}
}
}
(5).退出系统:
public class ExitOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("退出系统");
System.exit(0);
}
}
以下是普通用户菜单方法:
(1).退出系统和查找图书,是普通人员和管理员的共同方法
(2)归还图书:
public class ReturnOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("归还图书");
int currentSize = bookList.getUsedSize();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要归还的图书");
String name = scanner.nextLine();
for (int i = 0; i < currentSize; i++) {
//遍历,书架,已初始化的书
Book book = bookList.getBook(i);
if (book.getName().equals(name)) {
//看看isBorrowed返回,ture(已借出),还是false(未借出)
if (book.isBorrowed()) {
book.setBorrowed(false);
return;
}
}
}
System.out.println("错误,没有你要归还的图书");
}
}
(3)借阅图书:
public class BorrowOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("借阅图书");
int currentSize = bookList.getUsedSize();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要借阅的图书");
String name = scanner.nextLine();
for (int i = 0; i < currentSize; i++) {
//遍历,书架,已初始化的书
Book book = bookList.getBook(i);
if (book.getName().equals(name)) {
//看看isBorrowed返回,ture(已借出),还是false(未借出)
if (book.isBorrowed()) {
System.out.println("该书已经被借出");
return;
}
book.setBorrowed(true);//置为借出
System.out.println("借阅成功");
return;
}
}
System.out.println("没有找到你要借阅的那本书");
}
}