图书管理系统(框架实现)
要构建这样的一个系统,最难的其实就是找对象。让我们思考一下,在这样一个系统下,有哪些对象呢?最容易想到的,应该就是书和人。我们先从书开始考虑。
1、package 1:book
- class:Book ,我们可以创建一个Book类来实例化书本的对象,那么在Book类中应该设置书的哪些属性呢?根据简介,我们设置了name,author,price,type和isborrowed五个属性。为了体现封装性,我们都用private修饰它们。为了在类外部调用它们,我们又都为前四个成员变量设置了Getter and Setter方法(先不考虑isborrowed)。为了便于初始化,我们自己写一个包含前四个变量作为参数的构造方法。如下所示:
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;
}
为了打印出的格式与简介中所示一致,我们可以在Book类中重写toString方法:
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
( (isBorrowed == true) ? ",已借出" : ",未借出" )+
//", isBorrowed=" + isBorrowed +
'}';
}
原理:println打印时调用的是Object类中的toString方法,而所有类都默认继承了Object类,重写toString方法后,调用时发生动态绑定,调用子类重写的方法,导致打印格式改变。
- class :BookList,有了书本之后,我们还需要一个地方(数组)来存放、操作这些书,于是我们构建了BookList类,在其中定义一个数组Book[ ],同时创建变量usedSize来表示有多少位置被使用了。同样,我们使用private修饰,并提供Getter and Setter方法。我们还可以在BookList类中写一个构造方法创建数组对象,规定最大存放书本量与已使用书本量。如下:
public BookList() {
this.books = new Book[10];
this.usedSize = 0;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
接下来,我们就迎来了第一个难题:如何组织这些操作,让每一个操作都独立。
package 2 :operation
方法一:我们把每一个操作都写成一个类,需要时直接调用即可。
但是这种写法比较复杂,输入的不同需要使用多分支结构判断实现调用。
方法二:我们还可以定义一个接口IOPeration里面放入一个work方法(传入BookList),以便后面创建一个接口数组,在其中对应位置实例化对应的对象,实现类型的统一。
如下:
public interface IOPeration {
void work(BookList booklist);
}
package 3 :user
- class :User,我们也给用户创建一个类,在其中设置成员变量name,可以使用protected修饰。我们要实现面对管理员和普通用户打印不同的菜单。我们可以考虑触发动态绑定,实现多态。根据多态发生的条件,我们要:
1、创建AdminUser和NormalUser两个类来继承User类。
2、这两个子类重写User类中的menu方法。
由此,User类中的menu方法不必具体实现,可以设置为抽象类,增加安全性。
我们还需要定义一个ioPerations数组,实现对应下标(类)元素的实例化,调用其中的work方法,实现对应操作。
public abstract class User {
protected String name;
protected IOPeration[] ioPerations;
public User(String name) {
this.name = name;
}
public abstract int menu();
public void doOperation(int choice, BookList bookList) {
IOPeration ioPeration = this.ioPerations[choice];
ioPeration.work(bookList);
}
}
- class :AdminUser ,写一个构造方法来初始化接口数组,并重写menu方法。
public class AdminUser extends User {
public AdminUser(String name) {
super(name);
this.ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new AddOperation(),
new DelOperation(),
new ShowOperation()
};
}
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("0.退出系统");
System.out.println("************************");
System.out.println("请输入你的操作:");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
- class :NormalUser ,同上。
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
this.ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation()
};
}
public int menu() {
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;
}
}
main方法
我们要创建一个login方法来登录,choice变量接收后,进行判断,根据值的不同返回AdminUser或NormalUser对象。
public class Main {
public static User login() {
System.out.println("请输入你的姓名:");
Scanner scanner = new Scanner(System.in);
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 = new AdminUser(name);
// user = new NormalUser(name);
User user = login();
while (true) {//循环打印菜单
int choice = user.menu();
//根据你菜单返回的choice来执行对应的操作
user.doOperation(choice, bookList);
}
}
}