- 🍁 个人主页:爱编程的Tom
- 💫 本篇博文收录专栏:Java专栏
- 👉 目前其它专栏:c系列小游戏 c语言系列--万物的开始_
- 🎉 欢迎 👍点赞✍评论⭐收藏💖三连支持一下博主🤞
- 🧨现在的沉淀就是对未来的铺垫🎨
目录
前言
在这篇文章当中,我们需要编写一个面向对象思想的图书管理系统 ,运用了JavaSE基础语法当中的封装、继承、多态等思想和方法。
🍳设计的大体思路
首先需要找到我们所要创建的对象,即找对象-->创建对象-->使用对象。这里我们可以来看一下已经做好的例子,来分析该系统的需求。
从上图可以看出对象目前有三个,即管理员、用户、图书,以及各自对应增删改查的相关操作。
Ⅰ 管理系统菜单
🥕管理员菜单
1.查找图书
2.新增图书
3.删除图书
4.显示图书
0.退出系统
-----------------------------------------------------------------------
🥕用户菜单
1.查找图书
2.借阅图书
3.归还图书
0.退出系统
Ⅱ 搭建基本框架
- 首先新建一个Book包,然后建立一个Book类,设置好所需要的字段(此处默认未被借出)
private String name;//书名
private String author;//作者
private int price;//价格
private String type;//类型;
private boolean isBorrowed;//是否被借出,默认值为false
public Book(String name, String author, int price, String type) {
this.name = name;
this.author = author;
this.price = price;
this.type = type;
}
然后根据这些字段自动生成get、以及set方法
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;
}
然后我们需要生成这些字段,即成员变量的toString方法(这里对于借出做出更改,后面会讲)
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
((isBorrowed) ?" 该书已经借出!" : " 此书未借出!")+
//", isBorrowed=" + isBorrowed +
'}';
}
写到这里,对Book类的操作先告一段落
- 此时我们需要在当前Book包中新建一个Book List类(即模拟书架),用来存放书籍(位置、数量)
public class BookList {
private final Book[] books;
private int usedSize; //记录书架放书数量
public BookList() {
this.books = new Book[10];
this.books[0] = new Book("西游记","吴承恩",10,"小说");
this.books[1] = new Book("三国演义","罗贯中",9,"小说");
this.books[2] = new Book("水浒传","施耐庵",11,"小说");
this.books[3] = new Book("红楼梦","曹雪芹",12,"小说");
this.usedSize = 4;
}
这里默认已经放了四本书籍,现在我们为其提供相应的get、set方法(体现封装性)
--------------------------------------------------------------------------------------------------------------------------------
根据上述阐述,我们知道对象还有管理员和用户,这里提供一个user包,来建立相应的对象,模拟不同权限的登陆情况,所以在当前包中建立AdminUser类以及NormalUser类,由上图可知,这两个类拥有相同属性,我们可以提取出来新建一个User类,作为父类,由另外两个类来继承。
- User类
abstract public class User {
protected String name;
protected IOOperation[] ioOperations;
public User(String name) {
this.name = name;
}
}
- AdminUser类
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
};
}
- NormalUser类
public class NormalUser extends User {
public NormalUser(String name) {
super(name);
};
}
}
写到此处,我们就对图书以及管理、用户的类设置完毕
现在开始完成上图所展示的功能构架
由于让代码看上去更有可读性,我们重新建立一个包,命名为operation(针对接下来对书籍的一系列操作),因为所有的操作都是在书架上进行,即BookList上操作,所以这里我们定义一个IOOperation的接口,提供对书架的操作接口,接下来所有的操作都会继承这个接口来进行。
- 创建IOOperation接口
package operation;
import book.BookList;
public interface IOOperation {
void work(BookList bookList);
}
接下来,根据上述图片所展示的功能,我们新建不同的类,然后继承IOOperation接口来操作
-
AddOperation类
package operation;
import book.BookList;
public class AddOperation implements IOOPeration {
public void work(BookList bookList){
System.out.println("新增图书!");
}
}
-
BorrowOperation类
package operation;
import book.BookList;
public class BrrowOperation implements IOOPeration{
@Override
public void work(BookList bookList) {
System.out.println("借阅图书!");
}
}
-
DelOperation类
package operation;
import book.BookList;
public class DelOperation implements IOOPeration{
@Override
public void work(BookList bookList) {
System.out.println("删除图书!");
}
}
-
ExitOperation类
package operation;
import book.BookList;
public class ExitOperation implements IOOperation {
public void work(BookList bookList) {
System.out.println("退出系统!!!");
System.exit(0);
//这里要对bookList进行资源的手动回收
}
}
-
FindOpera类
package opera;
import book.BookList;
public class FindOpera implements IOOPeration{//继承
@Override
public void work(BookList bookList) {//重写IOPeration类中的work方法
System.out.println("查找图书!");
}
}
-
ReturnOperation类
package opera;
import book.BookList;
public class ReturnOperation implements IOOPeration{
@Override
public void work(BookList bookList) {
System.out.println("归还图书!");
}
}
-
ShowOperation类
package opera;
import book.BookList;
public class ShowOperation implements IOOPeration{
@Override
public void work(BookList bookList) {
System.out.println("打印所有图书!");
}
}
接下来,我们在创建的类中添加细节
首先我们需要两个不同角色的菜单:
🚩管理员菜单
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;
}
}
🚩用户菜单
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;
}
接下来,我们在src下新建一个类,提供一个可供测试的main方法:
import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
/**
* @Author: zzj
* @Description:
*/
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 = login();//此时不确定使用者是谁,AdminUser(name);或者NormalUser(name)
while (true) {
int choice = user.menu();//根据菜单返回的choice来执行对应操作
user.doOperation(choice, bookList);
}
}
}
注意:这里在login界面过后,我们依然不知道所调用的是谁的菜单,所以我们使用之前设置好的父类User,通过向上转型实现动态绑定,(这里需将User类设置为抽象类,在其中提供一个menu的抽象类方法,然后在AdminUser类和NormalUser类中重写这个方法)
abstract public class User {
protected String name;
protected IOOperation[] ioOperations;
public User(String name) {
this.name = name;
}
public abstract int menu();
}
这时,我们通过在main方法中设置选项,会调用不同界面的菜单。然后完善两个不同操作用户的类,最终修改为以下代码:
- AdminUser类
package user;
import operation.*;
import java.sql.SQLOutput;
import java.util.Scanner;
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
this.ioOperations = new IOOperation[] {
new ExitOperation(),
new FindOpera(),
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类
package user;
import operation.*;
import java.util.Scanner;
public class NormalUser extends User {
public NormalUser(String name) {
super(name);
this.ioOperations = new IOOperation[]{
new ExitOperation(),
new FindOpera(),
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;
}
}
这里我们需要在User类中添加如下代码,通过接口来调用对应的work方法,这里在main方法中设置了while循环,模拟选择0退出的选项。
public void doOperation(int choice, BookList bookList) {
this.ioOperations[choice].work(bookList);
//IOOperation ioOperation = this.ioOperations[choice];
//ioOperation.work(bookList);
}
到此为止,我们这个图书管理系统的基本框架已经搭好,可以测试一下 ~
Ⅲ 具体业务的实现
3.1 添加图书
新增图书信息,调用set方法,判断这本书是否已经存在,若不存在,可添加!
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class AddOperation implements IOOperation {
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("请输入您要新增图书的类型:");
scanner.nextLine();//此处Line和Int发生冲突,解决办法有三种
//1.将Int放在最后能顺利解决 2.将nextLine改为next 3. 多设置一次nextLine,将空格跳过
String type = scanner.nextLine();
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);
}
}
注意!!!
这里nextLine和nextInt发生冲突,最简单的办法就是,多设置一次nextLine(即scanner.nextLine()),将空格跳过去,其它方法已经写在源代码中 ,此外这里默认添加在最后的位置
3.2 借阅图书
判断所要借阅的图书是否存在或者已经借出,执行相应操作
book.setBorrowed(true);
3.3 删除图书
这里我们需要注意,由于我们设计的是一个简单的图书管理系统,未涉及到过多的复杂操作,所以我们默认:当删除一本书时,所产生的空缺位置由下一本书向前替代。
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 < currentSize; i++) {
Book tmp = bookList.getBook(i);
if (tmp.getName().equals(name)) {
index = i;
break;
}
}
if(i >= currentSize) {
System.out.println("没有您要删除的图书!!!");
return;
}
for (int j = index; j < currentSize-1; j++) {
Book book = bookList.getBook(j+1);
bookList.setBook(book,j);
}
bookList.setBook(null,currentSize-1);
bookList.setUsedSize(currentSize-1);//资源回收
System.out.println("删除成功!!!");
}
3.4 退出系统
添加以下代码就可以正常退出
System.exit(0);
示例:
3.5 查找图书
利用equals进行比较,对比查找!
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;
}
}
System.out.println("没有找到您所需的书籍,书名为: " + name);
}
3.6 归还图书
满足以下条件,执行操作
book.setBorrowed(false);
3.7 展示图书
由上文可知,我们已经添加了四本书籍,然后for循环遍历打印即可。
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);
}
}
展示效果:
这时,我们在前面的构造方法中,利用三目操作符(条件?符合输出:不符合输出),即将这里原本所展示的false改为了“此书已借出”和“此书未借出”两种状态。在Book类中修改如下代码:
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
((isBorrowed) ?" 该书已经借出!" : " 此书未借出!")+
//", isBorrowed=" + isBorrowed +
'}';
}
Ⅳ 完整代码
- Book
package book;
public class Book {
private String name;//书名
private String author;//作者
private int price;//价格
private String type;//类型;
private boolean isBorrowed;//是否被借出,默认值为false
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;
}
public void setBorrowed(boolean borrowed) {
isBorrowed = borrowed;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
((isBorrowed) ?" 该书已经借出!" : " 此书未借出!")+
//", isBorrowed=" + isBorrowed +
'}';
}
}
- BookList
package book;
/**
* @Author: zzj
* @Description:
*/
public class BookList {
private final Book[] books;
private int usedSize; //记录书架放书数量
public BookList() {
this.books = new Book[10];
this.books[0] = new Book("西游记","吴承恩",10,"小说");
this.books[1] = new Book("三国演义","罗贯中",9,"小说");
this.books[2] = new Book("水浒传","施耐庵",11,"小说");
this.books[3] = new Book("红楼梦","曹雪芹",12,"小说");
this.usedSize = 4;
}
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;
}
}
-
AddOperation
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
/**
* @Author: zzj
* @Description:
*/
public class AddOperation implements IOOperation {
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("请输入您要新增图书的类型:");
scanner.nextLine();//此处Line和Int发生冲突,解决办法有三种
//1.将Int放在最后能顺利解决 2.将nextLine改为next 3. 多设置一次nextLine,将空格跳过
String type = scanner.nextLine();
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);
}
}
-
BorrowOperation
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
/**
* @Author: zzj
* @Description:
*/
public class BorrowOperation implements IOOperation {
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
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class DelOperation implements IOOperation {
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 < currentSize; i++) {
Book tmp = bookList.getBook(i);
if (tmp.getName().equals(name)) {
index = i;
break;
}
}
if(i >= currentSize) {
System.out.println("没有您要删除的图书!!!");
return;
}
for (int j = index; j < currentSize-1; j++) {
Book book = bookList.getBook(j+1);
bookList.setBook(book,j);
}
bookList.setBook(null,currentSize-1);
bookList.setUsedSize(currentSize-1);//资源回收
System.out.println("删除成功!!!");
}
}
-
ExitOperation
package operation;
import book.BookList;
public class ExitOperation implements IOOperation {
public void work(BookList bookList) {
System.out.println("退出系统!!!");
System.exit(0);
//这里要对bookList进行资源的手动回收
}
}
-
FindOpera
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class FindOpera implements IOOperation {
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;
}
}
System.out.println("没有找到您所需的书籍,书名为: " + name);
}
}
-
IOOperation接口
package operation;
import book.BookList;
public interface IOOperation {
void work(BookList bookList);
}
-
ReturnOperation
package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class ReturnOperation implements IOOperation {
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
package operation;
import book.Book;
import book.BookList;
public class ShowOperation implements IOOperation {
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包---User
package user;
import book.BookList;
import operation.IOOperation;
abstract public class User {
protected String name;
protected IOOperation[] ioOperations;
public User(String name) {
this.name = name;
}
public abstract int menu();
public void doOperation(int choice, BookList bookList) {
this.ioOperations[choice].work(bookList);
//IOOperation ioOperation = this.ioOperations[choice];
//ioOperation.work(bookList);
}
}
- user包---AdminUser
package user;
import operation.*;
import java.sql.SQLOutput;
import java.util.Scanner;
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
this.ioOperations = new IOOperation[] {
new ExitOperation(),
new FindOpera(),
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;
}
}
- user包--NormalUser
package user;
import operation.*;
import java.util.Scanner;
/**
* @Author: zzj
* @Description:
*/
public class NormalUser extends User {
public NormalUser(String name) {
super(name);
this.ioOperations = new IOOperation[]{
new ExitOperation(),
new FindOpera(),
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方法测试
import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
/**
* @Author: zzj
* @Description:
*/
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 = login();//此时不确定使用者是谁,AdminUser(name);或者NormalUser(name)
while (true) {
int choice = user.menu();//根据菜单返回的choice来执行对应操作
user.doOperation(choice, bookList);
}
}
}
效果图: