本次就将主要使用java语言中的继承与多态,封装,接口等知识点,来综合性的设计与实现出一个简易的图书管理系统。
图书管理系统无非就两个角色, 管理员和普通用户, 他们实现的功能肯定也不一样
管理员主要分为: 查找图书, 新增图书, 删除图书, 显示图书, 退出图书
普通用户主要分为: 查找图书, 借阅图书, 归还图书, 退出系统
可以看下基本的实现框架如图:
1. 既然写的是图书管理肯定要有书, 我们就创建Book类, 包含图书名, 作者, 价格, 类别等等, 把这些 属性封装起来
2. 把这些书的属性封装起来, 存放到书架上. 所以创建一个书架BookList类, 相当存放到数组里面
3. 那接下来是不是还有我们的管理员AdminUser类和普能用户NormalUser, 进行图书的各种操作, 比如对图书的增删查改, 不同用户实现的功能也是不一样的
4. 为了实现图书的各种功能,如上图, 所以我们需要创建一个接口IOperation类来实现这些功能
5. 最后创建个Main类, 把上面的东西全部整合起来, 让他跑起来
看下所要创建的包和类
(1)Book类 - 图书类
在这里的书的属性有书名、作者、价格、类型以及是否被借出,这里我结合了封装性,将属性设置为private权限,这样的话要提供相应的get方法和set方法,以及提供一个构造方法但不包含是否被借出的属性, 因为布尔值的默认类型就是false,我们一开始书肯定是没借出的,当借出我们自己提供方法让false改成ture就行了, 所以这里重写了toString()方法来修改, 从而打印我们的数据
具体代码如下:
package 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;
}
//提供set ,get的方法
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) ? "已经借出":"未借出")+
'}';
}
}
(2)BookList类 - 书架类
BookList是用来存放我们的图书的, 我们定义个数组用来存放图书和记录当前图书的大小的属性,同样结合了封装性,将属性设置为private权限,和给定一个构造方法, 一开始书架上肯定是先放了书的, 所以会在构造方法中就先定义几本书, 然后通过get, set给获取下标从而找到这本书和书本数目
具体代码如下:
package Book;
public class BookList {
private Book[] book = new Book[10];//存放图书
private int usedSize;//记录当前多少本书
public BookList(){
//一开始就放了三本书
book[0] = new Book("三国演义", "罗贯中", 90,"小说");
book[1] = new Book("西游记", "吴承恩", 90,"小说");
book[2] = new Book("红楼梦", "曹雪芹", 90,"小说");
usedSize = 3;
}
/*
* 以下我们下标归定都是合法的
* */
//给定pos下标可以找到这本书
public Book getBook(int pos) {
return book[pos];
}
//给pos下标然后放一本书book
public void setBook(int pos, Book book) {
this.book[pos] = book;
}
//获取图书数量
public int getUsedSize() {
return usedSize;
}
//实时记录图书的数量
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
}
(1)IOperation接口
接下来我们需要实现有新增,删除,显示,查找等等,他们都需要遵循一定的规范,而这个规范就由接口IOperation来实现,其实就相当于一个桥梁。在增删查改等操作中,他们的主要方式就是工作,即work(),故接口中提供对应的work()方法供接口的实现类,即各种操作进行重写, 这里的参数是一个BookList类型, 利用了多态,以下的功能实现都是利用了多态,代码实现如下:
package operation;
import Book.BookList;
public interface IOperation {
void work(BookList bookList);
}
(2)AddOperation类 - 新增图书
我们需要将操作类实现IOperation接口,同时为重写的方法work()提供书架类。将这本书的全部信息都输入进去,在书架类中添加进去图书,再将书架中书的数量加1, 这里要利用set, get获取相对应的方法来达到我们的一个要求,代码如下:
package operation;
import Book.Book;
import Book.BookList;
import java.util.Scanner;
public class AddOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("新增图书");
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();
//new一个Book的对象把新增图书的信息给他传过去
Book book = new Book(name, author, price, type);
int currentSize = bookList.getUsedSize();//获取当前图书的数目
bookList.setBook(currentSize, book);/把新增的图书给放到书架上
bookList.setUsedSize(currentSize+1);//让当前图书的数目加1
System.out.println("新增图书成功");
}
}
(3)BorrowOperation类 - 借阅图书
很简单,就是从书架上面查找我们想要的书有没有,借助equals()方法来找, 有就返回true,然后借阅成功,没有就没借阅成功, 默认的还是false,代码如下:
package operation;
import Book.Book;
import Book.BookList;
import java.util.Scanner;
public class BorrowOperation implements IOperation{
public void work(BookList bookList) {
System.out.println("借阅图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要借阅的图书的名字:");
String name = scanner.nextLine();//输入要找和图书
int currentSize = bookList.getUsedSize();//获取当前图书的数目
for (int i = 0; i < currentSize; i++){//遍历下数组是否有
Book book = bookList.getBook(i);//获取i下标的图书
if (book.getName().equals(name)){//来比较要借阅图书是否有
book.setBorrowed(true);//有就把isBorrowed设置为true
System.out.println("借阅成功!");
return;
}
}
System.out.println("没有你要借阅的图书!");
}
}
(4)DelOperation类 - 删除图书
同样,从书架上查找是否有这本图书, 有就删除成功, 否则失败,代码如下:
package operation;
import Book.Book;
import Book.BookList;
import java.util.Scanner;
public class DelOperation implements IOperation{
public void work(BookList bookList) {
System.out.println("删除图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要删除的图书名");
String name = scanner.nextLine();//输入要删除的图书
int currentSize = bookList.getUsedSize();//获取当前图书数目
int i =0;
int flg = 0;//默认还没找到删除的标志
for (i = 0; i < currentSize; i++) {//遍历数组
Book book = bookList.getBook(i);
if (book.getName().equals(name)) {
flg = 1;//找到了改为1
break;
}
}
if (flg == 1){
for (int j = i; j < currentSize-1; j++) {
Book book = bookList.getBook(j);
book = bookList.getBook(j+1);//从要删除的图书的下一位往前覆盖掉
bookList.setBook(j, book);
}
bookList.setUsedSize(currentSize-1);//图书数目减1
System.out.println("删除成功");
}else {
System.out.println("没有你要删除的图书");
}
}
}
(5)DisplayOperation类 - 显示图书
直接遍历打印就行了,代码如下:
package operation;
import Book.Book;
import Book.BookList;
public class DisplayOperation implements IOperation{
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);
}
}
}
(6)ExitOperation类 - 查找图书
和前面的借阅图书差不多一样的思路的, 代码如下:
package operation;
import Book.Book;
import Book.BookList;
import java.util.Scanner;
public class FindOperation implements IOperation{
public void work(BookList bookList) {
System.out.println("查找图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要查找的图书的名字:");
String name = scanner.nextLine();
int currentSize = bookList.getUsedSize();
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("没有查到你要找的书");
}
}
(7)ReturnOperation类 - 归还图书
还是和借阅图书模块一样的思路, 先查找要归还的图书, 查找到了, 就用setBorrow()设置成false就行(这里不考虑是否已借出),代码如下:
package operation;
import Book.Book;
import Book.BookList;
import java.util.Scanner;
public class ReturnOperation implements IOperation{
public void work(BookList bookList) {
System.out.println("归还图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要归还的图书的名字:");
String name = scanner.nextLine();
int currentSize = bookList.getUsedSize();
for (int i = 0; i < currentSize; i++){
Book book = bookList.getBook(i);
if (book.getName().equals(name)){
book.setBorrowed(false);//查找到了归还,就设置成false
System.out.println("归还成功!");
return;
}
}
}
}
(8)ExitOperation类 - 退出系统
直接调用exit(0)方法, exit(0)表示正常退出, exit()使程序立即正常终止,如果状态值为0则认为正常推出
package operation;
import Book.BookList;
public class ExitOperation implements IOperation{
public void work(BookList bookList) {
System.out.println("退出系统!!!");
System.exit(0);//状态码
}
}
(1)User类 - 用户
首先我们的用户包含两部分:管理员和普通用户, 他们都是用户, 需要继承我们的User类, 子类中要都含有menu方法, 因为我们管理员和普通用户的操作菜单不同,因此依靠他们各自的类进行重写menu方法更加合适, 不同的子类的具体实现是不一样的。在的Main类中可以看到,是使用User发生多态(动态绑定)来调用不同的对象的,所以,一定会使用User来调用不同的menu方法,而父类没有这个方法,就要加上menu方法,但是这个可以没有具体的实现, 所以把这个menu方法变成了一个抽象方法就行了。这个User类,成了一个抽象类,抽象类的作用就是为了被继承的。在User类中,新增一个doOperation方法,能够将选择和具体的操作结合起来。代码如下:
package User;
import Book.BookList;
import operation.IOperation;
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接口当做是个数组,当传choice下标就会来调用对应的功能,然后调用父类work的方法,是利用了接口的多态来实现的, 就是发生了所谓的动态绑定
this.iOperations[choice].work(bookList);
}
}
(2)AdminUser类 - 管理员用户
我们在AdminUser类中可以看出重写menu方法,同时对iOperation数组进行初始化,根据不同下标调用不同的功能
package User;
import operation.*;
import java.util.Scanner;
public class AdminUser extends User {
public AdminUser(String name) {
super(name);
this.iOperations = new IOperation[]{
new ExitOperation(),
new FindOperation(),
new AddOperation(),
new DelOperation(),
new DisplayOperation()
};
}
public int menu() {
System.out.println("hello " + 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("请输入你的操作: ");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
(3)NormalUser类 - 普通用户
代码如下:
package User;
import operation.*;
import java.util.Scanner;
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("hello "+this.name+" 欢迎来到图书小练习");
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);
int choice = scanner.nextInt();
return choice;
}
}
到这里我们所有的框架都已经搭建好了,只需要在Main类中的main方法进行测试即可,代码如下
在Main类中,我们通过创建一个书架,同时写一个用户登录方法,菜单,以及doOperation方法,利用一个死循环一直进行选择操作,最后当用户选择退出系统时候会直接终止。
import Book.BookList;
import User.User;
import User.AdminUser;
import User.NormalUser;
import java.util.Scanner;
public class Main {
public static User login() {
System.out.println("请输入你的名字: ");
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
System.out.println("请选择你的身份: 1>: 管理员, >0: 普通用户");
int ret = scanner.nextInt();
if (ret == 1) {//身份的选择,0或1来调用不同的身份
return new AdminUser(str);
} else {
return new NormalUser(str);
}
}
public static void main(String[] args) {
BookList bookList = new BookList();//创建个书架,用来放图书
User user = login();//用户登录
while (true){
int choice = user.menu();//调用菜单
user.doOperation(choice,bookList);//通过传choice下标来选择不同的功能
}
}
}
登录 - Gitee.com