图书管理系统 —— Java篇
每博一文案
刘同写过这样一句话,以前总是去解释去理论,是怕,
怕自己得罪人,怕自己被人灭了,怕那些不停窜动的小感受
现在不去解释,不去理论,还是怕,
怕浪费自己的时间,怕自己模糊了焦点,怕影响了现实生活中的胃口,
长大后,才发现就是慢慢学会沉默,不动声色地过好自己的生活。
小时候,稍有不如意就会大哭一场,让别人知道自己很委屈。
现在即便受到别人的误解,也不愿同别人解释,
不是因为自己的承受能力强了,而是明白了,有些人说
与不说都是一样。
———————— 一禅心灵庙语
文章目录
简介
- 该项目利用了 类,继承,接口,多态(向上转型),抽象类,重写,封装,分布式多文件集成实现的
主要的需求
- 书籍的实体属性:书名,作者,书的价格,书的类型,书的出借状态
- 两种用户:图书管理员,普通用户
- 图书管理员具有的功能:退出系统,查找图书,新增图书,删除图书,显示所有图书,切换用户,清除所有图书
- 普通用户具有的功能:退出系统,查找图书,借阅图书,归还图书,切换用户
对应类的设计
- 首先我们需要让 ——> 对应的类 存放到 ——> 对应的包 中,所以我们先 创建对应的包 用来存放其 类
- 这里我们创建三个 包: 分别是:
- books包 : 用来存放有关书籍的类
- operation包 :用来存放对应用户功能的类
- user包 :用来存放用户信息的
- 对应相关的 包 建好以后,就可以减少相对应的命名、等等上的不必要的冲突了。
- 接下来,就可以创建对应的 类 的方向了
- 我们需要创建的所有的 包和类 如下图:所示
创建设计有关书籍的类
- 在books包 下我们创建有关的类
Book 类
-
从上图中,我们可以知道了 书 具有的那些 属性 从而进行设置
-
- 需要对该 Book类 的创建 有参数构造方法 ,用于后面的的相关的赋值操作,这里的 isBoorrowed 不用重新定义,默认是 false 未借出状态 ,后面写一个根据该 boolean 布尔值,显示出 借出,未借出的状态 如:private String lendState() 方法
- 重写 toString() 的方法,用于打印 book类类型 ,注意不要忘了,用上**@Override注解** 的提示作用,我们可以使用上 Ait + Insert 快捷键,快速 重写 toString( )方法 ,在稍稍加以修改即可
- 为了 实现封装 ,我们这里需要对该 类成员 进行 set,get 的封装 ,同样我们可以使用快捷键 Ait + Insert
-
具体代码如下:
package books;
/**
* 定义Bool 书的一个类的类型
*/
public class Book {
private String name; // 书名
private String author; // 书的作者
private double price; // 书的价格
private String type; // 书的类型
private boolean isBorrowed; // 书的借出状态
public Book(String name, String author, double price, String type) { // 构造方法
this.name = name;
this.author = author;
this.price = price;
this.type = type;
// isBoorrowed 不用重新定义,默认是 false 未借出状态,
}
/*
根据 isBoorrwed 类型的布尔值,修改对应的书的出借状态
*/
private String lendState() {
String state = "未借出";
if(this.isBorrowed) {
state = "已借出";
}
return state;
}
@Override // 注解:重写toString()方法,未打印 book 类类型做准备
public String toString() {
String condition = this.lendState();
return "Book{" +
"书名: '" + name + '\'' +
", 作者: '" + author + '\'' +
", 价格: " + price +
"元, 类型: '" + type + '\'' +
", 书籍状态: " + condition +
'}';
}
/**
* 对该类成员的封装
* 下面是对该类中的类成员的 set 和 get 方法
* @return
*/
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 double 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;
}
}
BookList 类
- 创建一个名为 BookList 的类,实现 Book类类型的顺序表, 用于存放对应的书籍,对于 顺序表的理解以及实现 ,大家参考如下 博客 🔜🔜🔜 图 + 码 = 顺序表 —— C语言实现(附有源码实现) 以及 顺序表 —— Java附加代码 大家都可以参考参考
-
- 创建Book 类类型的数组,private Book[] books = new Book[100]
- 这里我们——> 构造方法 先存放到 三本书籍
- 使用 set,get 封装该 顺序表,我们可以使用快捷键 Ait + Insert ,需要注意的是该快捷键创建的几个set,get 不是我们想要的,需要改下一下:如:public Book getBooks(int pos) ,传数组的下标,取出 books数组 对应的 book类类型 ,以及 public void setBooks(int pos,Book book) 传数组的下标,和 新的一个 book类型 ,实现对 books数组 的 添加元素
- 具体代码实现如下:
package books;
/**
* 定义存放书籍的顺序表
*/
public class BookList {
private Book[] books = new Book[100]; // 定义书类类型的数组,用于存放数组
private int usedSize = 0; // 记录书籍有效个数
/**
* 构造方法
* 初始三本书,
* 并记录书籍个数
*/
/*
使用构造方法,存放三本书籍
* */
public BookList() {
this.books[0] = new Book("三国演义","罗贯通",100.0,"小说");
this.books[1] = new Book("西游记","吴承恩",100.0,"小说");
this.books[2] = new Book("红楼梦","曹雪芹",120.0,"古典小说");
this.usedSize = 3; // 记录书籍有效个数
}
/**
* 对该类中的类成员,类数组 封装
* 对该类中的类成员,类数组的 set 和 get 的方法
* @return
*/
public Book getBooks(int pos) { // 封装对,下标访问该 Book类型的 book数组
return books[pos];
}
public void setBooks(int pos,Book book) { // 封装对,Book类型,book 数组赋值
this.books[pos] = book;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
}
有关操作用户的类的设计
- 在 user包 中创建有关用户的类
User 抽象类
-
- 首先我们创建 User抽象类 ,在该类中创建一个 接口上对应的数组protected IOperation[] operations ,用于对应用户上的功能上的选择
- 在该类中定义 一个对应用户的菜单的 **抽象方法 public abstract int menu() ** 让,
- 再创建一个方法用于,接口数组operations[choice].work(bookList) ,让对应用户调用对应功能的==.work(bookList)== 类,
- 让管理员Admin类 和普通员工NormalUser类 继承该 User抽象类 ,让该抽象类作为 父类 从而 子类 可以调用该父类的属性和方法,以及该子类必须重写该 public abstract int menu(); 菜单的抽象方法;
- 具体的代码实现如下:
package user;
import books.BookList;
import operation.IOperation;
/**
* 定义用户抽象类,
*
*/
public abstract class User { // 抽象类
protected String name;
protected IOperation[] operations; // 初始化数组对应,用户对应功能的实现,表示通过
public User(String name) {
this.name = name;
}
public abstract int menu(); // 菜单抽象方法,
public void doOperation(int choice, BookList bookList) {
operations[choice].work(bookList); // 调用对应 功能的 work 接口中的抽象类
// 对应的用户,选择对应的功能查找图书
}
}
Admin 管理员类
- 该类继承 抽象类User ,public class Admin extends User ——> 必须调用父类中的 构造方法 ,同时在该类中的构造方法中,对父类中的接口数组super.operations = new IOperation[] 元素的赋值,其元素是对应 管理员 用户所具有的功能上的方法 ,也就是说这里的 数组的元素 是 方法 ,以菜单上的选择的数值:1,2,3,访问该接口IOperation[] 数组从而调用对应的功能上的方法
- 重写父类 抽象类User中的菜单打印的 抽象方法 public int menu() ,不要晚了重写的标注性注解 @Override ,用于错误提醒,可以使用 快捷键Ctrl + o
- 具体代码实现如下:
package user;
import operation.*;
import java.util.Scanner;
/**
* 对应 Admin 管理员用户
*/
public class Admin extends User{
public Admin(String name) {
super(name);
// 定义相关的用户功能,父类的User 抽象类,的数组,
/*
实现了同一个接口的类,可以定义在该接口的数组中
* */
super.operations = new IOperation[]{
new ExitOperation(),
new FindOperation(),
new AddOperation(),
new DelOperation(),
new DisplayOperation(),
new SwitchOperation(),
new RemoveOperation()
};
}
/**
* 对应用户 Admin的功能菜单
* @return
*/
@Override
public int menu() {
Scanner scanner = new Scanner(System.in);
int choice = 0;
System.out.println("**********************************");
System.out.println("尊敬的管理员 您好! \"" + super.name + "\" 欢迎使用图书管理系统");
System.out.println("0.退出系统");
System.out.println("1.查找图书");
System.out.println("2.新增图书");
System.out.println("3.删除图书");
System.out.println("4.显示所有图书");
System.out.println("5.切换用户");
System.out.println("6.清除书籍");
System.out.println("***********************************");
System.out.print("请输入您的选择:> ");
choice = scanner.nextInt();
while (choice < 0 || choice > 6 ) {
System.out.print("您的选择有误,请重新选择:>");
choice = scanner.nextInt();
}
return choice;
}
}
Code 类
- 这是对于 Admin管理员 用户的身份的一个验证功能,的一个密码机制,这里我设置的密码为 字符串:“123” ,为什么是字符串,因为密码是存在 字母和符号的 ,所以用字符串类型定义,使用字符串比较判断库函数 equals 进行一个真假的判断,返回值,错误机会只有 三次 ,三次已过退出系统,使用 System.exit(0); 可以直接正常退出程序
System.exit(int status) :是用来结束当前正在运行中的java虚拟机。
System.exit(0) :status是零参数,那么表示正常退出程序。
System.exit(1) :status是1或者非零参数,那么表示非正常退出程序
- 具体代码实现如下:
package user;
import java.util.Scanner;
/**
* Admin 密码机制
*/
public class Code {
public static boolean passWord() {
Scanner scanner = new Scanner(System.in);
String code = "123";
for (int i = 3; i > 0; i--) {
System.out.print("请输入管理员密码: ");
code = scanner.next();
if(code.equals("123")) {
System.out.println("密码正确");
return true;
} else {
System.out.println("密码错误");
System.out.print("你还有"+(i-1)+"次机会,请重新输入密码:> ");
}
}
System.out.println("三次密码错误,退出系统");
System.exit(0); // 退出程序
return false; //这条语句并不会被执行到的, 因为上面已经结束程序了
}
}
NormalUser 普通用户
- 该类和 Admin管理员类 基本上是一样的,同样继承了 public class NormalUser extends User 的 User抽象类 , 对父类中的接口 protected IOperation[] operations 元素上的赋值,这里赋值的是 用户所具有 的功能上的方法,这就是说这里的 数组的元素 是 方法 ,这里是以菜单上数值的选择 1,2,3,通过访问该接口IOperation[] 数组的下标,调用 用户 所具有的功能
- 同样 重写 父类 (User抽象类) 的菜单的 抽象方法(public int menu() ), 不要忘了 注解 @Override 用于错误的提醒,可以使用 快捷键 Ctrl + o
- 具体的代码实现如下:
package user;
import operation.*;
import java.util.Scanner;
/**
* 对应普通用户的定义
* 对 User抽象类的继承
*/
public class NormalUser extends User {
public NormalUser(String name) {
super(name);
super.operations = new IOperation[]{
new ExitOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation(),
new SwitchOperation()
};
}
/**
* 该用户 NormalUser 的应用菜单
*/
@Override
public int menu() {
Scanner scanner = new Scanner(System.in);
int choice = 0;
System.out.println("****************************************************");
System.out.println("尊敬的普通用户 您好! \""+super.name+"\" 欢迎使用图书管理系统");
System.out.println("0.退出系统");
System.out.println("1.查看图书");
System.out.println("2.借阅图书");
System.out.println("3.归还图书");
System.out.println("4.切换用户");
System.out.println("****************************************************");
System.out.print("请输入您的选择:> ");
choice = scanner.nextInt();
// scanner.close(); // 关闭 IO ,不可以关闭
while(choice < 0 || choice > 4) {
System.out.print("您的选择有误,请重新选择:> ");
choice = scanner.nextInt();
}
return choice;
}
}
有关对应功能上的类的实现
- 在包operation中,首先定义一个 **接口IOperation ** ,这个接口与上面的 Admin类,NormalUser类,User抽象类 中的 接口数组operations[choice].work(bookList) 是相对应的,
IOperation 接口
- 创建该接口的目的是为了,User抽象类的接口数组,元素为实现该接口的类中 work 抽象方法 ,通过下标可以调用到对应的功能上的方法,
- 在该接口中创建一个 void work(BookList bookList) 抽象方法
- 所有功能上的类,都要实现该接口
- 具体代码实现如下:
package operation;
import books.BookList;
import user.NormalUser;
/**
* 创建该包中 operation 中对应用户的 功能的接口
* 定义接口 IOperation
*/
public interface IOperation {
void work(BookList bookList); // 抽象方法
}
AddOperation 类
- 该AddOperation类的作用是为了实现 :新增图书的功能
- 该类实现接口IOperation接口 ,public class AddOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 新增图书的功能
- 这里我们 使用顺序表的 尾插法 ,对 book类类型的插入 到顺序表中
- 顺序表的 尾插法 大家可以参考:🔜🔜🔜 图 + 码 = 顺序表 —— C语言实现(附有源码实现) 以及 顺序表 —— Java附加代码 大家都可以参考参考
- 具体代码实现如下:
package operation;
import books.Book;
import books.BookList;
import user.NormalUser;
import java.util.Scanner;
/**
* 新增图书
* AddOperation 实现接口 IOperation
* 重写 接口中的 work 抽象方法
*/
public class AddOperation implements IOperation {
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
System.out.println("新增图书");
System.out.println("请输入图书的名字:");
String name = scanner.nextLine();
System.out.println("请输入图书的作者:");
String author = scanner.nextLine();
System.out.println("请输入图书的价格:");
double price = scanner.nextDouble();
System.out.println("请输入图书的类型");
String type = scanner.next();
/*
插入书的顺序表中
使用顺序表的尾插法
注意封装问题
*/
Book book = new Book(name,author,price,type); // 实例创建一个新的 Book类,然后赋值该 book 数组
int curSize = bookList.getUsedSize
(); // 获取该书的顺序表的长度
bookList.setBooks(curSize,book); // 尾插法,在curSize下标插入,刚刚新建立book
bookList.setUsedSize(curSize+1); // 有效个数加 1
System.out.println("添加图书成功");
}
}
BorrowOperation 类
- 该 BorrowOperation类对应的功能是对 借阅书籍功能上的实现
- 该类实现接口IOperation接口 ,public class BorrowOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 借阅书籍的功能
- 这里我们遍历 顺序表——> 判断是否存在该书籍,——> 存在判断该书籍的状态是否为借出
- 具体代码实现如下:
package operation;
import books.Book;
import books.BookList;
import user.NormalUser;
import java.util.Scanner;
/**
* 借阅书籍
* BorrowOperation 实现接口 IOperation
* 重写 接口中的 work抽象方法
*/
public class BorrowOperation implements IOperation {
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
String name = null;
System.out.println("借阅书籍");
System.out.println("请输入你所需要借阅的书名");
name = scanner.nextLine();
/*
遍历查找
并判断该书籍的状态,是否可以借出
* */
for (int i = 0; i < bookList.getUsedSize(); i++) {
Book book = bookList.getBooks(i); // 封装了,通过getBooks 下标访问数组,取出数值book 类的数值
if(book.getName().equals(name)) { // 使用方法 equals 判断字符串的相等
if(false == book.isBorrowed()) { // 判断书籍的状态是否可以借出
book.setBorrowed(true); // 借出后,修改书籍的状态
System.out.println("借阅成功");
} else {
System.out.println("抱歉,该书籍已经被借出了");
}
return;
}
}
System.out.println("抱歉,没有你所需要的书籍");
return; // 遍历完没有该,书籍
}
}
DelOperation 类
- 该 DelOperation类 对应的功能是 删除图书
- 该类实现接口IOperation接口 ,public class DelOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 删除图书
- 这里我们使用顺序表中的删除法 具体可以参考 🔜🔜🔜 🔜🔜🔜 图 + 码 = 顺序表 —— C语言实现(附有源码实现) 以及 顺序表 —— Java附加代码 大家都可以参考参考
- 具体代码的实现如下:
package operation;
import books.Book;
import books.BookList;
import user.NormalUser;
import java.util.Scanner;
/**
* 删除图书
* DelOperation 实现接口 IOperation
* 重写接口中的 work 的抽象方法
* 1.首先找到该书籍存在的下标位置,
* 2,通过尾删法,从 pos +1 的位置前移动
* 3.顺序表的有效值减一
*/
public class DelOperation implements IOperation {
@Override
public void work(BookList bookList) {
System.out.println("删除图书");
Scanner scanner = new Scanner(System.in);
String name = null;
System.out.println("请输入删除的书名:");
name = scanner.nextLine();
int i = 0;
for ( i = 0; i < bookList.getUsedSize(); i++) {
Book book = bookList.getBooks(i);
if(book.getName().equals(name)) {
break; // 找到了,跳出循环
}
}
/*
* 判断跳出循环是因为 找到了,还是没有找到
* 当 i 等于 顺序表的长度,表示没有找到,因为数组的下标,访问从 0 开始
*/
if(i == bookList.getUsedSize()) {
System.out.println("抱歉,没有你要删除的书籍");
return ; // 没有直接退出后面的插入的执行
}
/*
尾删法,从pos + 1的位置从后向前覆盖,删除
* */
for (int pos = i; pos < bookList.getUsedSize()-1; pos++) {
// 注意这里的bookList.getUsedSize()-1 数组的长度减1 ,因为数组的有效长度是没有值的,
// 数组从 0 开始计数的
/* bookList[pos] = bookList[pos+1];
* 这是错误的
* 错在哪里 ???
* boolList[pos] 不是数组,更不是顺序表,是一个类
* boolList 只是一个存放,定义了顺序表的一个类,它不是数组,而是通过
* 它间接的访问到我们的 一个顺序表
* 该类中有一个顺序表 book*/
Book book = bookList.getBooks(pos + 1); // 取出要删除节点的后一个节点
bookList.setBooks(pos,book); // 覆盖要删除的节点
}
bookList.setUsedSize(bookList.getUsedSize() - 1); // 跳出循环,顺序表的有效长度 -1
System.out.println("删除成功");
return ;
}
}
DisplayOperation 类
- 该 DisplayOperation类 的作用是 :显示所有图书
- 该类实现接口IOperation接口 ,public class DisplayOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 显示所有图书
- 这里我们通过循环遍历,打印 Book类类型 就可以了
- 具体代码的实现如下:
package operation;
import books.Book;
import books.BookList;
import user.NormalUser;
/**
* 显示所有图书
* 遍历顺序表
* DisplayOperation 实现接口 IOperation
* 重写接口中的 work 抽象方法
*/
public class DisplayOperation implements IOperation {
@Override
public void work(BookList bookList) {
System.out.println("显示所有图书");
for (int i = 0; i < bookList.getUsedSize() ; i++) {
Book book = bookList.getBooks(i); // 取出下标每个图书book类类型
System.out.println(book); // 打印 book 因为重写了toString
// System.out.println(); 在 toString 中存在自动换行
}
}
}
ExitOperation 类
- 该 ExitOperation类 的作用是:退出系统
- 该类实现接口IOperation接口 ,public class ExitOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 退出系统
- 我们使用 System.exit(0) 方式正常退出程序
System.exit(int status) :是用来结束当前正在运行中的java虚拟机。
System.exit(0) :status是零参数,那么表示正常退出程序。
System.exit(1) :status是1或者非零参数,那么表示非正常退出程序
- 具体代码的实现如下:
package operation;
import books.BookList;
import user.NormalUser;
/**
* 退出系统
* ExitOperation 实现接口 IOperation
* 重写接口中 work 的抽象方法
*/
public class ExitOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("退出系统");
System.exit(0);
}
}
FindOperation 类
- 该 FindOperation类 的作用是:查找图书
- 该类实现接口IOperation接口 ,public class FindOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 查找图书
- 遍历循环顺序表
- 具体代码的实现如下:
package operation;
import books.Book;
import books.BookList;
import user.NormalUser;
import java.util.Scanner;
/**
* 查找你所需要的书籍 -- 遍历出来
* FindOperation 实现类 IOperation
* 重写接口中的抽象方法 Work
*/
public class FindOperation implements IOperation{
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
String name = null;
System.out.println("查找书籍");
System.out.println("请输入你所需查找的书籍");
name = scanner.nextLine();
for (int i = 0; i < bookList.getUsedSize(); i++) {
Book book = bookList.getBooks(i);
if(book.getName().equals(name)) { // 使用 equals 方法字符串的比较判断,找出来
System.out.println("找到");
System.out.println(book); // 找到并打印该 book 类类型
return;
}
}
System.out.println("抱歉,没有该书籍"); // 循环遍历完不存在,该书籍
}
}
RemoveOperation 类
- 该 RemoveOperation类 的作用是实现 :清除图书
- 该类实现接口IOperation接口 ,public class RemoveOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 清除图书
- 我们直接将 **记录有效个数 置为 0 ** 就可以了,0 本书籍
- 具体代码实现如下:
package operation;
import books.BookList;
import user.NormalUser;
/**
* 清除书籍
* RemoveOperation 实现接口 IOperation
* 重写接口中的 work 抽象方法
*/
public class RemoveOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("清除书籍");
bookList.setUsedSize(0); // 直接将顺序表的有效记录置为 0
System.out.println("清除成功");
}
}
ReturnOperation 类
- 该 ReturnOperation类 的作用是 归还图书
- 该类实现接口IOperation接口 ,public class ReturnOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 归还图书
- 通过 遍历顺序表——> 找到该书籍 ——> 改变该书籍的出借状态 private boolean isBorrowed; // 书的借出状态 ,
- 具体的代码实现如下:
package operation;
import books.Book;
import books.BookList;
import user.NormalUser;
import java.util.Scanner;
/**
* 归还书籍
* ReturnOperation 实现接口 IOperation
* 重写接口中的 work 抽象方法
*
*/
public class ReturnOperation implements IOperation{
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
String name = null;
System.out.println("归还书籍");
System.out.println("请输入归还的书名");
name = scanner.nextLine();
for (int i = 0; i < bookList.getUsedSize(); i++) {
Book book = bookList.getBooks(i); // 封装,通过存放顺序表的类,bookList 取出对应下标的
if(book.getName().equals(name)) { // book 类类型的数值
book.setBorrowed(false); // 改变书籍的状态,未借出
System.out.println("归还成功");
return; // 归还成功,停止向下执行
}
}
System.out.println("没有你所需要归还的书籍"); // 顺序表遍历完,不存在该书籍
}
}
SwitchOperation 类
- 该 SwitchOperation类 的作用是用于 切换用户
- 该类实现接口IOperation接口 ,public class SwitchOperation implements IOperation ,实现了该接口,必须重写该接口中所有的抽象方法 work 抽象类,在该抽象类中实现 切换用户
- 通过 引用类型的传参(浅拷贝) 、向上转型 对用户重写方法的调用
- 具体代码实现如下:
package operation;
import books.BookList;
import user.Admin;
import user.Code;
import user.NormalUser;
import user.User;
import java.util.Scanner;
/**
* 切换用户
* SwitchOperation 实现接口 IOPeration
* 重写接口中的抽象方法
*/
public class SwitchOperation implements IOperation{
@Override
public void work(BookList bookList) {
User user = login(); // 调用,login 获取对应 用户的向上转型,调用对应的重写
while(true) {
if(null !=user) {
int choice = user.menu();
user.doOperation(choice,bookList);
} else {
break;
}
}
}
private User login() {
Scanner scanner = new Scanner(System.in);
String name = null;
int who = 0;
System.out.print("请输入您的姓名:> ");
name = scanner.nextLine();
System.out.print("请输入您的身份登入:1.表示管理员、0.表示普通用户::> ");
who = scanner.nextInt();
while(who != 1 && who != 0) {
System.out.print("选择错误,请重新选择:> "); // 只有 1 或 0
who = scanner.nextInt();
}
if(1 == who) {
if(Code.passWord()) { //管理员,需要密码
return new Admin(name);
}else{
return null;
}
}
if(0 == who) {
return new NormalUser(name); // 注意返回类型,父类,向上转型
}
return null; // 这一步是不会执行的
}
}
Main方法的实现
- 该方法是 进入图书管理系统的入口,
- 因为进行了,大量的封装,以及多态,接口,继承,抽象类,向上转型,这里的 main 简单,代码量少
- 高内聚,低耦合
- 具体代码如下:
import books.BookList;
import operation.SwitchOperation;
public class MainTest {
public static void main(String[] args) {
BookList bookList = new BookList(); // 定义书籍的存储顺序表
SwitchOperation switchOperation = new SwitchOperation(); // 实例化 切换用户的类
switchOperation.work(bookList); // 调用其中的,切换功能
}
}
效果显示
*有关的代码文件大家可以🔜🔜🔜 gitee中的图书管理系统
最后:
限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵 —— 多多益善,谢谢大家!后会有期,江湖再见!