天梯无捷径,唯有苦攀登。 一起加油,小伙伴们!!
目录
文末附总代码链接
1. 实现思路:
1).图书管理系统有不同的用户,一个是管理员用户,一个是普通用户;
2).管理员和普通用户的操作不一样;
3).以面向对象的思路去实现,我们需要找对象、创建对象、使用对象!
2. 那么如何找对象呢?
我们很容易就能够想到两个对象:书和人
所以我们首先要建立一个书的包,然后在包中创建一个书的类
然后我们图书不可能只有一本吧?我们的图书管理系统也不可能只管理一本书吧?
于是我们就需要一个东西来存放书,可以近似理解成放书的书架,这个书架可以放若干本书,所以我们需要用数组去操作,于是我们创建一个存放数组的类,于是我们book包中就有了两个类
( 注:图片来自网络,如有侵权,请联系删除 )
3. Book类的实现
我们就想想Book这个书的类有哪些属性? 书名?作者?价格?类型?是否被借出?
//Book.java
package book;
public class Book {
private String name;//书名
private String autho;//作者
private int price;//价格
private String type;//类型
private boolean isBorrowed;//是否被借出
}
由于这些属性是private修饰的,我们就需要提供 getter 和 setter 方法
//Book.java
package book;
public class Book {
private String name;//书名
private String autho;//作者
private int price;//价格
private String type;//类型
private boolean isBorrowed;//是否被借出
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAutho() {
return autho;
}
public void setAutho(String autho) {
this.autho = autho;
}
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;
}
}
我们的这些属性需要构建输入的对象,所以我们需要提供构造方法进行初始化
public Book(String name, String autho, int price, String type) {
this.name = name;
this.autho = autho;
this.price = price;
this.type = type;
}
注意一个地方:我们这里没有构造 isBorrowed !!为什么呢?
isBorrowed是一个 boolean类型,默认是 false ,如果我们实例化一本书,默认这本书是不是没有被借出?所以我们的构造方法就不需要加isBorrowed
同时我们这里还需要重写一个toString方法!
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", autho='" + autho + '\'' +
", price=" + price +
", type='" + type + '\'' +
", isBorrowed=" + isBorrowed +
'}';
}
我们Book这个类便完成了!!!
Book类总代码:
package book;
public class Book {
private String name;//书名
private String autho;//作者
private int price;//价格
private String type;//类型
private boolean isBorrowed;//是否被借出
public Book(String name, String autho, int price, String type) {
this.name = name;
this.autho = autho;
this.price = price;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAutho() {
return autho;
}
public void setAutho(String autho) {
this.autho = autho;
}
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 + '\'' +
", autho='" + autho + '\'' +
", price=" + price +
", type='" + type + '\'' +
", isBorrowed=" + isBorrowed +
'}';
}
}
4. BookList类的实现
在书架上存放若干本书,那一定是个Book类型的数组,同时我们还需要记录当前书架存放了多少本书
public class BookList {
private Book[] books;
private int usedSize;//记录当前存放的书籍数量
}
接着便是创建构造方法进行初始化
public BookList() {
this.books = new Book[10];
this.usedSize = 0;
}
由于我们还不知道books里面放什么书,我们先放着,但是书架我们是知道的
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
BookList便暂时完成啦!
BookList类总代码:
package book;
public class BookList {
private Book[] books;
private int usedSize;//记录当前存放的书籍数量
public BookList() {
this.books = new Book[10];
this.usedSize = 0;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
}
( 注:图片来自网络,如有侵权,请联系删除 )
5. 用户的操作
管理员用户有什么操作? 查找图书?新增图书?删除图书?显示图书?退出系统?
普通用户有什么操作? 查找图书?借阅图书?归还图书?退出系统?
那么我们如何把不同用户的操作分离开来呢?
有些操作是公用的,有些操作是分开的,我们要想办法去组织这些操作
思路:每个操作都独立开来, 分别写成一个类
我们先创建一个包,用来创建相关操作的类
5.1 AddOperation类
这个类用于新增图书,哪里新增呢?BookList中新增
package operation;
import book.BookList;
public class AddOperation {
public void work(BookList bookList){
System.out.println("新增图书!");
}
}
5.2 FindOperation类
跟上面一样,我们操作的就是BookList
package operation;
import book.BookList;
public class FindOperation {
public void work(BookList bookList){
System.out.println("查找图书!");
}
}
5.3 DelOperation类
package operation;
import book.BookList;
public class DelOperation {
public void work (BookList bookList){
System.out.println("删除图书!");
}
}
5.4 ShowOperation类
package operation;
import book.BookList;
public class ShowOperation {
public void work(BookList bookList) {
System.out.println("显示图书!");
}
}
5.5 ExitOperation类
package operation;
import book.BookList;
public class ExitOperation {
public void work(BookList bookList){
System.out.println("退出系统!");
}
}
5.6 BorrowedOperation类
package operation;
import book.BookList;
public class BorrowedOperation {
public void work(BookList bookList){
System.out.println("借阅图书!");
}
}
5.7 ReturnOperation类
package operation;
import book.BookList;
public class ReturnOperation {
public void work(BookList bookList){
System.out.println("归还图书!");
}
}
5.8 重点思路
思路:我们可以发现不管是哪个操作,都是BookList类型的参数,所以将来我们可以把几个类组织在一起,用接口接收,所以我们需要去实现这个接口
package operation;
import book.BookList;
public interface IOperation {
void work(BookList bookList);
}
然后把前面的几个操作全部实现这个接口,然后重写work方法
为什么要这么做?
如果若干个类都能实现这个接口,将来写这样的代码很好用:
这样做是为了类型的统一
( 注:图片来自网络,如有侵权,请联系删除 )
6. 用户
操作已经有了,我们现在进行人相关的,人相关的有哪些? 管理员? 普通用户?
我们先建立一个user包
6.1 用户类
用户有什么?用户名?
package user;
public class User {
protected String name;
public User(String name) {
this.name = name;
}
}
6.2 管理员类
package user;
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
}
}
6.3 普通用户类
package user;
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
}
}
这样我们便简单的完成了 人,现在回到Main方法类中进行登录设计
7. 登录设计
7.1 用户身份选择的设计
进入main方法时,我们首先定义一个方法 login 进行一个用户名字的输入,然后让用户进行身份选择,注意:这个方法login既可以返回普通用户类(NormalUser),也可以返回管理员(AdminUser),所以这个方法的类型定义为User,这里便发生了向上转型
import user.AdminUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
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) {
}
}
7.2 菜单的设计
当调用login时,我们的User就会接收一个对象,此时这个user到底指向的是管理员对象还是普通对象?这个是我们不知道的,但是不管是指向哪个对象,我们都需要一个菜单,于是我们就需要调用菜单。让普通用户和管理员有各自的菜单,于是我们回到普通用户类和管理员类分别创建一个菜单。
package user;
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
}
public void menu(){
System.out.println("******普通用户菜单******");
System.out.println("1.查找图书");
System.out.println("2.借阅图书");
System.out.println("3.归还图书");
System.out.println("0.退出系统");
System.out.println("*********************");
}
}
package user;
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
}
public void 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("********************");
}
}
这样菜单便完成了,我们这个时候可以直接通过 user.menu(); 的方式进行菜单调用吗?让我们试试
报错了!!为什么会报错? 我们仔细看,user是什么?这是个父类!父类能够直接调用子类的方法吗?很明显不行,所以我们这里要父类有menu,然后子类进行重写,所以我们回到User写菜单,这个菜单需要具体实现吗?不需要,所以我们设置为抽象方法。
package user;
public abstract class User {
protected String name;
public User(String name) {
this.name = name;
}
public abstract void menu();
}
这个时候我们调用menu时便会发生动态绑定。
( 注:图片来自网络,如有侵权,请联系删除 )
7.3 用户要选择操作的设计
当菜单打印完成,我们就需要输入操作了,所以我们要在菜单后面补上一条代码让用户知道此时要输入操作,我们让choice去接收这个操作,并返回这个操作,我们就需要更改menu的类型为int,那么父类User中的menu也需要同步改成int。
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
}
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;
}
}
接下来便是重难点了,打起精神小伙伴们!!如何将管理员的操作组织起来,将普通用户的操作组织起来,组起来放到哪里?这就回到上文 5.8 的重点思路 了。
首先在User中定义一个数组 protected IOperation[ ] Ioperations;
package user;
import operation.IOperation;
public abstract class User {
protected String name;
protected IOperation[] Ioperations;
public User(String name) {
this.name = name;
}
public abstract int menu();
}
现在有个问题:这个数组有没有初始化? 没有初始化!!!数组的初始化要么为它赋值,要么让它为null。这里的每个元素都没有初始化,因为没有给它们分配空间,那我们现在给它们分配空间,那我们站在User的角度该给它分配多大的空间?10?20?我们并不清楚,以NormalUser为例,NormalUser继承了父类的name 和 protected IOperation[ ] Ioperations;
那我们也会面临一个问题,该给它分配多大的空间?
注意这两种写法的区别,array这种在定义同时直接赋值了
于是我们就要这样设计:
因为我们的操作类都实现了接口IOperation,相当于父类引用引用子类对象,所以我们可以这样:
为什么要这样设计?大家看我们的菜单:
是不是把菜单的操作和数组的下标相结合了?下标为0就退出,下标为1查找图书······
那么问题又出来了,这样设计不会和AdminUser的菜单混一起吗?毕竟我们用户的菜单是不一样的
我们看这:
我们这里有个if - else语句,会同时返回两个对象吗?这里要么返回管理员,要么返回普通用户,只会返回一个对象。如果我们返回AdminUser,会初始化下图的NormalUser吗?不会!!!
AdminUser也如上面操作一样
那么我们现在把两个用户的操作数组都完成好了,当我们程序运行到下图的login(),是不是就返回了对应对象的一个菜单?要么是普通用户的菜单,要么是管理员的菜单,这个时候数据准备好了,假如是管理员的菜单,是不是要获得这个数组里面某个方法(上图的数组)?所以我们在user里面创建个方法,把choice传进去,选择1就访问这个数组的1下标,选择2就访问这个数组的2下标(如下图2)
当用户选择1,那么doOperation就会返回1下标,访问对应的方法,如下图
我们拿到的是对象,如何访问对象?这就相当于
this.ioperations[choice] = new ExitOperation();
那就说明前面这部分 this.ioperations[choice] 就相当于一个引用,这个对象有什么方法吗?有个work方法,所以我们可以通过 . 号来调用(匿名对象用 . 访问方法),而这个work方法的参数是书架
当我们运行代码时候会有好几本书,这里创建一个对象bookList
会自动调用不带参数的构造方法
走到这里的时候,我们是不是可以初始化对应的书?我们不管它,我们回到main方法中传入第二个参数,User也需要传进第二个参数
当choice为1时,调用这个数组 this.Ioperations[choice] 的1下标,然后访问它的work方法
1下标刚刚说了是FindOperation,然后把bookList给它,这不就是调用我们这个数组this.Ioperations[choice] 的1下标这个work方法了吗?
如果铁子们还是看不懂上图这行代码,也可以这样写这行代码,会更加容易理解
7.4 实验一下
这里查找一次就结束进程了,我们可以把代码循环起来
public static void main(String[] args) {
BookList bookList = new BookList();
// user = new AdminUser(name);
// user = new NormalUser(name);
User user = login();
while(true){
int choice = user.menu();//根据菜单返回的choice来进行对应的操作
user.doOperation(choice,bookList);
}
}
}
同时要注意一个点,进程结束,我们要对自源进行手动回收,或者有人说这不是会自动回收吗?但是其实谁回收都不好使,最好还是我们自己动手回收,别老是靠系统!!!
public class ExitOperation implements IOperation{
public void work(BookList bookList){
System.out.println("退出系统!");
//应该要对 bookList 资源 手动回收
System.exit(0);
}
}
( 注:图片来自网络,如有侵权,请联系删除 )
8. 完善相关操作功能
为了方便测试,我们先在书架上放几本书进去
8.1 查找图书
我们要依靠书名查找图书,那么我们是不是应该遍历数组,目前我们的书只有3本,而数组的空间是10,那么我们只需要遍历目前书的数量即可,这个时候便要引用到一个之前设计的变量了
但是这还有个问题就是usedSize和books是被private修饰的,那么我们有没有提供getter方法?
既然提供了getter方法,那么我们就可以这样使用了
int currentSize = bookList.getUsedSize();
而books没有提供getter方法,那么我们就要补上去
这样我们就可以获得数组下标了,因为name是String类型,就需要利用equals来进行判断是否为要找的书
实现代码
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("查找图书!");
System.out.println("请写出你要查找图书的书名:");
Scanner scanner = new Scanner(System.in);
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;
}
}
//说明代码没有return出去,所以没有你要找的书
System.out.println("没有你要找的这本书,书名为:" + name);
}
}
( 注:图片来自网络,如有侵权,请联系删除 )
8.2 新增图书
图书都有书名、作者、价格、类型四个属性,所以我们要对这些属性进行输入,我们是不是要先提醒用户输入这些属性?
import javax.swing.*;
import java.util.Scanner;
public class AddOperation implements IOperation{
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("请输入你要新增图书的价格:");
int price = scanner.nextInt();
System.out.println("请输入你要新增图书的类型:");
String type = scanner.next();
}
}
当有了这四个属性我们就可以实例化一本书了,有了书的对象才可以新增一本书
Book book = new Book(name,author,price,type);
那么问题来了,新增一本书,应该放到数组的哪个位置,这里就不复杂处理,我们默认放到最后位置,在数据存储结构中,假设下标3和下标4,在下标3的位置为空的情况下,是不允许在下标4的位置进行存储的!!
我们新增图书可以利用currentSize这个记录图书数量的变量,我们新增一本书就让它++。在新增图书前,我们还需要进行判断,这本书是否已经存进去了?而这个判断的代码其实跟查找图书的没多大区别,
//此时就可以构造出一个书的对象
Book book = new Book(name,author,price,type);
int currentSize = bookList.getUsedSize();
for(int i = 0; i < currentSize; i++) {
Book tmp = bookList.getBook(i);
if (tmp.getName().equals(name)) {
System.out.println("存在这本书,不能重复添加!");
return;
}
}
如果没有重复添加,那就走到循环的外面,进行新增图书,新增往数组的哪里放呢?我们需要在BookList里设置一个方法,给Book提供位置,我们要在pos位置存放一本书,那么我们就需要在参数部分传书给它
public void setBook(Book book,int pos) {
books[pos] = book;
}
//没有重复的书,开始新增
bookList.setBook(book,currentSize);
bookList.setUsedSize(currentSize + 1);
实现代码
package operation;
import book.Book;
import book.BookList;
import javax.swing.*;
import java.util.Scanner;
public class AddOperation implements IOperation{
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("请输入你要新增图书的价格:");
int price = scanner.nextInt();
System.out.println("请输入你要新增图书的类型:");
String type = scanner.next();
//此时就可以构造出一个书的对象
Book book = new Book(name,author,price,type);
int currentSize = bookList.getUsedSize();
for(int i = 0; i < currentSize; i++) {
Book tmp = bookList.getBook(i);
if (tmp.getName().equals(name)) {
System.out.println("存在这本书,不能重复添加!");
return;
}
}
//没有重复的书,开始新增
bookList.setBook(book,currentSize);
bookList.setUsedSize(currentSize + 1);
}
}
8.3 显示图书
其实就是前面写的FindOperation类
实现代码
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("查找图书!");
System.out.println("请写出你要查找图书的书名:");
Scanner scanner = new Scanner(System.in);
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;
}
}
//说明代码没有return出去,所以没有你要找的书
System.out.println("没有你要找的这本书,书名为:" + name);
}
}
8.4 删除图书
删除图书,我们首先要先判断有没有这本书,没有这本书我们能删吗?所以先来个for循环判断有没有存在这本书,这段代码其实就是Add功能的代码,如果找到这本书,我们要返回这本书的所在的下标,这里index = -1,其实就是用来判断是否找到这本书的,如果找到这本书,那么index就会改变,同时记录要删除的图书的下标
System.out.println("请输入你要删除图书的书名:");
int currentSize = bookList.getUsedSize();
int index = -1;
String name = scanner.nextLine();
int i = 0;
for( i = 0; i < currentSize; i++) {
Book tmp = bookList.getBook(i);
if (tmp.getName().equals(name)) {
index = i;
break;//记录下来了 要删除图书的名字
}
}
if(i == -1) {
System.out.println("没有你要删除的图书!");
return;
}
//可以删除了
那么如何删除呢?很简单,假设我们要删除 西游记 , 那么我们只要让红楼梦把西游记覆盖掉,然后Java再把红楼梦覆盖掉,currentSize-- ,这样就可以了,同时我们的index记录了要删除的数据下标,这样也便于我们进行覆盖操作
我们先利用getter方法获取j+1位置的书,然后通过setter方法给到 j 这位置,进行覆盖
for (int j = index; j < currentSize-1; j++) {
//bookList[j] = bookList[j+1];
Book book = bookList.getBook(j+1);
bookList.setBook(book,j);
}
注意:这里数组的条件currentSize要-1,不然会越界 ,你看下图,如果index=3时候,进入循环,然后j + 1是不是就= 4,然后越界了?
但这里还存在一个问题,我们3下标的空间没用了,但是还是占着空间,这就存在内存泄漏问题了,所以我们需要去主动把它置为null。同时这样也可以预防我们将上图2下标的java用别的书给删除了或者用其他书给覆盖了,理论上应该没有存java这本书了,但是3下标还存着java这本书的情况
bookList.setUsedSize(currentSize-1);
bookList.setBook(null,currentSize-1);
实现代码
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("请输入你要删除图书的书名:");
int currentSize = bookList.getUsedSize();
int index = -1;
String name = scanner.nextLine();
int i = 0;
for( i = 0; i < currentSize; i++) {
Book tmp = bookList.getBook(i);
if (tmp.getName().equals(name)) {
index = i;
break;//记录下来了 要删除图书的名字
}
}
//
if(i == -1) {
System.out.println("没有你要删除的图书!");
return;
}
//可以删除了
for (int j = index; j < currentSize-1; j++) {
//bookList[j] = bookList[j+1];
Book book = bookList.getBook(j+1);
bookList.setBook(book,j);
}
bookList.setUsedSize(currentSize-1);
bookList.setBook(null,currentSize-1);
}
}
( 注:图片来自网络,如有侵权,请联系删除 )
8.5 借阅图书
首先让用户输入要借阅的书名,然后判断这本书是否存在,接着就是利用setBorrowed方法,将它置为true,那么就成功了
同时要注意没借出成功的情况,让用户知道没这本书
System.out.println("没有你要借阅的图书:"+name);
我们测试一下
最后 是否借出 这样是不是很难看?我们修改一下,在book类中修改toString,运用三目操作符
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", autho='" + autho + '\'' +
", price=" + price +
", type='" + type + '\'' +
( (isBorrowed == true) ? "已借出" : "未借出") +
", isBorrowed=" + isBorrowed +
'}';
}
实现代码
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowedOperation implements IOperation{
public void work(BookList bookList){
System.out.println("借阅图书!");
System.out.println("请写出你要借阅图书的书名:");
Scanner scanner = new Scanner(System.in);
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(true);
System.out.println("借阅成功!");
return;
}
}
System.out.println("没有你要借阅的图书:"+name);
}
}
8.6 归还图书
实际上就是在 8.5 借阅图书 的代码上微调,把 true 改成 false 即可
实现代码
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class ReturnOperation implements IOperation{
@Override
public void work(BookList bookList){
System.out.println("归还图书!");
System.out.println("请写出你要归还图书的书名:");
Scanner scanner = new Scanner(System.in);
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);
System.out.println("归还成功!");
return;
}
}
System.out.println("没有你要归还的图书:"+name);
}
}
9. 总代码
Main.java
import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
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 = new AdminUser(name);
// user = new NormalUser(name);
User user = login();
while(true) {
int choice = user.menu();//根据菜单返回的choice来进行对应的操作
user.doOperation(choice,bookList);
}
}
}
book包
Book.java
package book;
public class Book {
private String name;//书名
private String autho;//作者
private int price;//价格
private String type;//类型
private boolean isBorrowed;//是否被借出
public Book(String name, String autho, int price, String type) {
this.name = name;
this.autho = autho;
this.price = price;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAutho() {
return autho;
}
public void setAutho(String autho) {
this.autho = autho;
}
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 + '\'' +
", autho='" + autho + '\'' +
", price=" + price +
", type='" + type + '\'' +
( (isBorrowed == true) ? "已借出" : "未借出") +
", isBorrowed=" + isBorrowed +
'}';
}
}
BookList.java
package book;
public class BookList {
private Book[] books;
private int usedSize;//记录当前存放的书籍数量
public BookList() {
this.books = new Book[10];
this.books[0] = new Book("三国演义","罗贯中",10,"小说");
this.books[1] = new Book("西游记","吴承恩",13,"小说");
this.books[2] = new Book("红楼梦","曹雪芹",11,"小说");
this.usedSize = 3;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public Book getBook(int pos) {
return books[pos];
}
public void setBook(Book book,int pos) {
books[pos] = book;
}
}
operation包
AddOperation.java
package operation;
import book.Book;
import book.BookList;
import javax.swing.*;
import java.util.Scanner;
public class AddOperation implements IOperation{
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("请输入你要新增图书的价格:");
int price = scanner.nextInt();
System.out.println("请输入你要新增图书的类型:");
String type = scanner.next();
//此时就可以构造出一个书的对象
Book book = new Book(name,author,price,type);
int currentSize = bookList.getUsedSize();
for(int i = 0; i < currentSize; i++) {
Book tmp = bookList.getBook(i);
if (tmp.getName().equals(name)) {
System.out.println("存在这本书,不能重复添加!");
return;
}
}
//没有重复的书,开始新增
bookList.setBook(book,currentSize);
bookList.setUsedSize(currentSize + 1);
}
}
BorrowedOperation.java
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowedOperation implements IOperation{
public void work(BookList bookList){
System.out.println("借阅图书!");
System.out.println("请写出你要借阅图书的书名:");
Scanner scanner = new Scanner(System.in);
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(true);
System.out.println("借阅成功!");
return;
}
}
System.out.println("没有你要借阅的图书:"+name);
}
}
DelOperation.java
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("请输入你要删除图书的书名:");
int currentSize = bookList.getUsedSize();
int index = -1;
String name = scanner.nextLine();
int i = 0;
for( i = 0; i < currentSize; i++) {
Book tmp = bookList.getBook(i);
if (tmp.getName().equals(name)) {
index = i;
break;//记录下来了 要删除图书的名字
}
}
//
if(i == -1) {
System.out.println("没有你要删除的图书!");
return;
}
//可以删除了
for (int j = index; j < currentSize-1; j++) {
//bookList[j] = bookList[j+1];
Book book = bookList.getBook(j+1);
bookList.setBook(book,j);
}
bookList.setUsedSize(currentSize-1);
bookList.setBook(null,currentSize-1);
}
}
ExitOperation.java
package operation;
import book.BookList;
public class ExitOperation implements IOperation{
public void work(BookList bookList){
System.out.println("退出系统!");
//应该要对 bookList 资源 手动回收
System.exit(0);
}
}
FindOperation.java
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("查找图书!");
System.out.println("请写出你要查找图书的书名:");
Scanner scanner = new Scanner(System.in);
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;
}
}
//说明代码没有return出去,所以没有你要找的书
System.out.println("没有你要找的这本书,书名为:" + name);
}
}
IOperation.java
package operation;
import book.BookList;
public interface IOperation {
void work(BookList bookList);
}
ReturnOperation.java
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class ReturnOperation implements IOperation{
@Override
public void work(BookList bookList){
System.out.println("归还图书!");
System.out.println("请写出你要归还图书的书名:");
Scanner scanner = new Scanner(System.in);
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);
System.out.println("归还成功!");
return;
}
}
System.out.println("没有你要归还的图书:"+name);
}
}
ShowOperation.java
package operation;
import book.Book;
import book.BookList;
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);
}
}
}
user包
AdminUser.java
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 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;
}
}
NormalUser.java
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 BorrowedOperation(),
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;
}
}
User.java
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){
//this.Ioperations[choice].work(bookList);
IOperation iOperation = this.Ioperations[choice];
iOperation.work(bookList);
}
}
( 注:图片来自网络,如有侵权,请联系删除 )
希望对大家有所帮助,感谢观看!!!