今天我们来利用接口来实现一个图书管理系统。
主要就是实现上述功能。
在正式写代码之前我们需要明白我们需要什么类,需要什么接口,类与类之前需不需要继承。
创建各个类和接口
首先我们需要一个 Test 类来运行整个程序。
书自然要放在书架上,因此我们需要一个BookList(书架)类 ,但是我们知道,一个数组是无法有放字符串又放整型的,因此我创建了一个Book类,里面有书的name,author,price,exist作为这个类的成员变量。而BookList中则存放Book类型的数组。具体实现后面细讲。
我们可以看到管理员和借阅者是有着两套图书管理系统的,因此我们也需要分别创建两个类
AdmUser(管理员系统)和NorUser(借阅者系统)。
其次是实现功能的各个类,ExitBooks(退出系统), FindBooks(查找书籍), AddBooks(新增书籍), DeleteBooks(删除书籍), ShowBooks(展示书籍), BorrowBooks(借阅书籍), ReturnBooks(归还书籍)。
由于我们有两套相似系统,不妨将将两个系统看做子项,创建一个抽象父类 User ,方便我们后续的操作。
在功能实现时我们如果能将各个实现功能的类放进一个数组,这样我们只需输入下标就能调用相应类。为此我们需要一个接口 Port ,我们需要所有的功能类实现Port接口。通过向上转型创建一个 Port类型的数组,这样就可以通过下标调用各个类。
大概就是这个样子。
接下来来写对应代码吧。
代码
1,Book
每一本书都有自己的名字,作者,价格....我们需要创建相对的成员变量,并利用构造方法进行赋值。
public class Book {
private String name;
private String author;
private int price;
private boolean exist;
public Book(String name, String author, int price){
this.name=name;
this.author=author;
this.price=price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", exist=" + exist +
'}';
}
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 boolean getExist() {
return exist;
}
public void setExist(boolean exist) {
this.exist = exist;
}
}
由于我进行了封装,成员变量是由 private 修饰的,因此又添加了一系列get,set方法。
同时对 toString 方法进行重写,方便我们后续的数据打印。
2,BookList
BookList是存放Book类型数组的,我们自然要新建一个面向Book类的对象。
private Book[] books=new Book[10];
这样我们就创建了一个类型为Book,叫做books的数组。除此之外我们还需要书架上一共有几本书。
private int userSize;
由userSize来记录书的数量。
不要忘记通过构造方法来进行初始化。
public BookList(){
books[0] = new Book("三国演义","罗贯中",10);
books[1] = new Book("西游记","吴承恩",15);
books[2] = new Book("红楼梦","曹雪芹",5);
userSize=3;
}
books和userSize也进行了封装,因此也需要一系列get,set方法。代码整体是这样。
public class BookList {
private Book[] books=new Book[10];
private int userSize;
public BookList(){
books[0] = new Book("三国演义","罗贯中",10);
books[1] = new Book("西游记","吴承恩",15);
books[2] = new Book("红楼梦","曹雪芹",5);
userSize=3;
}
public Book getBooks(int i) {
return books[i];
}
public void setBooks(Book Books,int i) {
this.books[i] = Books;
}
public int getUserSize() {
return userSize;
}
public void setUserSize(int userSize) {
this.userSize = userSize;
}
}
3,Port接口
每一个功能实现的类作用都很单一,就是实现对应的功能。因此Port 接口中我们只需要定义一个work方法就行了,而实现Port接口的各个类,都只需要重写这个work方法就可以了。
interface Port {
void work(BookList bookList);
}
当然,bookList(书架)我们需要作为参数传进去。
然后我们直接从Test类开始写。
4,Test
public class Test {
public static void main(String[] args) {
System.out.println("欢迎使用图书馆系统");
System.out.println("请问你是 1:管理员 2:借阅者");
Scanner scanner=new Scanner(System.in);
//确认是管理者还是借阅者
int choice=scanner.nextInt();
scanner.nextLine();
System.out.println("请输入你的名字");
String name = scanner.nextLine();
User user = null;
if(choice==1){
user=new AdmUser(name);
}else{
user=new NorUser(name);
}
BookList bookList=new BookList();
user.doWork(bookList);
}
}
可以看到,在进行完准备工作后,就来到确认身份的环节。由于 User 类为抽象类无法创建实例,因此我这暂时将 user 置为null。我们知道 AdmUser 和 NorUser是User 的子类。因此这里通过向上转型,确认user的类型。然后创建booklist实例对书架进行初始化。dowork方法代表着正式进行工作(稍后讲)。
5,User
在介绍AdmUser类和NorUser类之前还是要先讲一下它们的父类User类。
public abstract class User {
public String name;
public User(String name){
this.name=name;
}
//执行方法的数组
public Port[] array;
public abstract void menu();
public abstract void doWork(BookList bookList);
}
这便是User类的全部内容。
我们需要name变量来接收先前输入的数据。
array数组是Port类型的,利用向上转换存放各个实现功能的类。
menu则是菜单,每一个系统都有自己的菜单。
在dowork类中进行一系列的调用,实现目的。
6,AdmUser
即然继承了父类中的这么多内容那就要派上用场。
public class AdmUser extends User{
public AdmUser(String name){
super(name);
array=new Port[]{
new ExitBooks(),
new FindBooks(),
new AddBooks(),
new DeleteBooks(),
new ShowBooks()
};
}
public void menu(){
System.out.println(" AdmUser::menu");
System.out.println(" 欢迎"+this.name+"使用图书馆系统");
System.out.println(" 1:查找书籍");
System.out.println(" 2:新增书籍");
System.out.println(" 3:删除书籍");
System.out.println(" 4:展示书籍");
System.out.println(" 0:退出系统");
System.out.println("");
}
@Override
public void doWork(BookList bookList) {
int choice;
Scanner scanner=new Scanner(System.in);
while(true){
menu();
choice=scanner.nextInt();
array[choice].work(bookList);
}
}
}
在执行构造方法时,需要先将父类初始化。因此这里需要
super(name);
然后我们根据mean中的顺序,在array数组中一次输入对应的类。
public AdmUser(String name){
super(name);
array=new Port[]{
new ExitBooks(),
new FindBooks(),
new AddBooks(),
new DeleteBooks(),
new ShowBooks()
};
}
public void menu(){
System.out.println(" AdmUser::menu");
System.out.println(" 欢迎"+this.name+"使用图书馆系统");
System.out.println(" 1:查找书籍");
System.out.println(" 2:新增书籍");
System.out.println(" 3:删除书籍");
System.out.println(" 4:展示书籍");
System.out.println(" 0:退出系统");
System.out.println("");
}
这样我们就完成了准备阶段,然后就是dowork进行正式操作了,
我定义了个choice,这代表着我要选择的操作。
然后写了一个死循环,这样的话除非我选择了0:退出系统,不然系统就会一直运行下去。
每一次进入这个循环,就要重新打印菜单,就要重新选择要进行的操作,然后work。
值得注意的是,由于数组里存的是类,因此要想正常工作我们需要这样写
array[choice].work(bookList);
这样才能调用对应的 work 方法。
7,NorUser
基本逻辑和AdmUser差不多。
public class NorUser extends User{
public NorUser(String name){
super(name);
array=new Port[]{
new ExitBooks(),
new FindBooks(),
new ShowBooks(),
new BorrowBooks(),
new ReturnBooks(),
};
}
public void menu(){
System.out.println(" NorUser::menu");
System.out.println(" 欢迎"+this.name+"使用图书馆系统");
System.out.println(" 1:查找书籍");
System.out.println(" 2:展示书籍");
System.out.println(" 3:借阅书籍");
System.out.println(" 4:归还书籍");
System.out.println(" 0:退出系统");
System.out.println("");
}
@Override
public void doWork(BookList bookList) {
int choice;
Scanner scanner=new Scanner(System.in);
while(true){
menu();
choice=scanner.nextInt();
array[choice].work(bookList);
}
}
}
8,AddBooks等进行功能实现得类。
public class AddBooks implements Port{
@Override
public void work(BookList bookList) {
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();
Book book=new Book(name,author,price);
int size=bookList.getUserSize();
bookList.setBooks(book,size);
//书籍数量加一
size++;
bookList.setUserSize(size);
System.out.println("添加成功");
}
}
这些类都需要实现Port接口,然后重写work方法。这里就放一个AddBooks的代码,后续代码有时间更新。