众所周知,图书馆里得先有一定数量的书,而书本放在书架上是有编号的,然后有管理员整理这些书架上的图书,才会有顾客来看书、借书和还书。而图书管理系统就是面向用户,方便用户对图书进行操作的一种交互式系统,此处也就体现了面向对象编程的特点。下图是本文的编写依据

准备工作:在社区版IDEA中新建一个空项目,在 src 文件夹下新建一个名为 book 的包,用来存放图书和书架两个实体类;再新建一个名为 user 的包,用来存放用户的文件。
目录
[一、创建图书类 Book](#一、创建图书类 Book)
[二、创建书架类 BookList](#二、创建书架类 BookList)
[9.1 退出系统](#9.1 退出系统)
[9.2 显示图书](#9.2 显示图书)
[9.3 查找图书](#9.3 查找图书)
[9.4 新增图书](#9.4 新增图书)
[9.5 借阅图书](#9.5 借阅图书)
[9.6 删除图书](#9.6 删除图书)
一、创建图书类 Book
本类是最好创建的,只需要封装好图书所有的属性,并通过IDEA编译器生成其他方法即可。(当前 isBorrow 属性并没有设置 get 和 set 方法,因为 Boolean 默认值是 fals,即图书一开始被定义之后都是没有被借出的,在新增图书对象的时候就不用输入该属性。后续如果需要用上的话就加上。)
java
package book;
public class Book {
private String name; // 书名
private String author; // 作者
private double price; // 单价
private String type; // 类型
private boolean isBorrow; // 是否被借出
public Book(String name, String author, double 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 double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isBorrow() {
return isBorrow;
}
public void setBorrow(boolean borrow) {
isBorrow = borrow;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
", isBorrow=" + isBorrow +
'}';
}
}
对于是否借出输出的信息值要么是 true 要么是 false,应该修改为显示"已借出"/"未借出"汉字信息,因此可以用三目运算符修改 toString() 方法:
java
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
((isBorrow == true) ? ", 已借出" : ", 未借出") +
//", isBorrow=" + isBorrow +
'}';
}
二、创建书架类 BookList
图书和书架是 a part of 的关系,或者说 书架和图书是 has a 的关系,这里就得运用到组合的知识(在我的文章"面向对象三大特征之一------继承"中有所提及)
和继承类似,组合 也是一种表达类之间关系的方式,也是能够达到代码重用的效果。组合并没有涉及到特殊的语法 (诸如 extends 这样的关键字),仅仅是将一个类的实例作为另外一个类的字段。
将图书类实例成数组表示可以存放若干本图书,此处将其容量定为10本,并定义了一个表示有效数据个数的成员变量,用于统计实际存放的图书数量。
因为先有书才能管理,因此使用构造方法初始化刚开始存放的图书信息。但是为什么要用构造方法?
因为在实例化书架这个对象的时候就会直接调用构造方法,也就达到了获取已有图书信息的效果。
java
package book;
public class BookList {
private Book[] books = new Book[10];
private int useSize; // 有效的数据个数【实际存放书本的个数】
public BookList(){
this.books[0] = new Book("三国演义","罗贯中",59.8,"小说");
this.books[1] = new Book("西游记","吴承恩",59.8,"小说");
this.books[2] = new Book("红楼梦","曹雪芹",59.8,"小说");
this.useSize = 3;
}
}
三、创建用户
因为管理员和普通用户都是管理系统的用户,他们存在着共性,因此将共性抽取编写一个抽象类。
java
package user
public abstract class User {
protected String name;
public User(String name) {
this.name = name;
}
}
这个类看似代码很简单,但实际上有一些细节需要注意:
1、name 的修饰符,不应该被封装,因为抽象类是为了被继承的,即如果该属性被 private 修饰,那么子类无法对该属性进行操作;如果想给该属性进行适当的限制,用 protected 比 public 更好;
2、添加构造方法是为了子类继承该类之后,对父类的成员进行初始化。
然后创建管理员和普通用户两个子类。
java
package user;
public class AdmUser extends User{ //管理员
public AdmUser(String name) {
super(name);
}
}
java
package user;
public class NormalUser extends User{ // 普通用户
public NormalUser(String name) {
super(name);
}
}
四、菜单
对于管理员和普通用户来说,管理权限不一样,因此在进入系统之后显示的操作菜单栏应该也不一样。因此需要分别在两个类中定义不同的菜单:
java
package user;
import java.util.Scanner;
public class AdmUser extends User{
public AdmUser(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("***********************");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的操作:");
int choice = scanner.nextInt();
}
}
java
package user;
import java.util.Scanner;
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("*********************");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的操作:");
int choice = scanner.nextInt();
}
}
五、登录
每个人进入管理系统都要登录自己的账号并选择自己的身份,我们简化成只需要输入名字和选择身份即可进入系统。
定义一个 Main 类作为程序主入口,所有的操作都集中在此类当中。
这一步骤的重点是如何根据用户输入的值调用正确身份对象的操作。
java
import user.AdmUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
public class Main {
public static User login(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的姓名:");
String n = scanner.nextLine();
System.out.println("欢迎" + n + "来到图书管理系统");
System.out.println("请输入您的身份,1、管理员 2、普通用户");
int choice = scanner.nextInt();
if (choice == 1){
return new AdmUser(n);
}else if (choice == 2){
return new NormalUser(n);
}else {
return null;
}
}
public static void main(String[] args) {
User user = login();
assert user != null; // 用assert断言关键字判空
user.menu();
}
}
用到了向上转型,将 login 方法返回值类型定义为父类,并在 main 方法中用 User 引用接收。此时需要注意的是,要想调用 menu 方法,必须 User 类中有该方法才行,因为已经被向上转型了,不能调用子类中特有的方法,只能调用父类的方法。也就是说需要在前面编写过的父类中添加 menu(),运行时将发生动态绑定。
java
package user
public abstract class User {
protected String name;
public User(String name) {
this.name = name;
}
public abstract void menu(); // 抽象方法,等着被子类初始化
}
完成上述代码运行之后将得到下面的显示结果:
六、操作
用户其实是通过查看书架上的位置从而对图书进行间接性操作,因此应该将操作的动作写到 BookList 类上,但是因为不同的用户操作不同,因此不能全部都编写到 BookList 上,否则一旦将其实例化就难以根据对应的操作菜单实现相应的操作。因此应将这些功能分开编写到不同的类当中。
但是又该如何根据对象的不同调用不同的操作呢?
此时需要运用到接口的知识,因为即使是不同的操作,属于同一个行为标准的就可以定义为接口。也可以定义为一个抽象类,但是"操作"这个功能只需要一行代码,不需要常规变量或者方法,所以没有必要定义成抽象类。
步骤:新建一个包,命名为 ioperation 或者 operation ,将查找图书、借阅图书、归还图书、新增图书、删除图书、显示图书和退出系统这些功能的所有类都归属于这个包下。
java
package ioperation;
public interface IOperation {
void work(BookList bookList); // 因为需要对书架上的书进行操作,所以传参是必要的
}
java
package ioperation;
public class AddOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("新增图书......");
}
}
此处只以新增图书 AddOperation 类为例,其余功能类定义方法与之类似,因此省略。

到了用户根据菜单提示输入不同的值以调用不同的操作这个步骤,我们需要将用户输入的值作为 menu() 方法的返回值:
java
package user;
import java.util.Scanner;
public class AdmUser extends User{
public AdmUser(String name) {
super(name);
}
public int menu(){ // 修改了这一行
//System.out.println("欢迎"+ this.name + "来到图书管理系统"); // main方法中传name值到子类,因此可以被直接调用
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("***********************");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的操作:");
int choice = scanner.nextInt();
return choice; // 返回用户输入的值
}
}
java
package user;
import java.util.Scanner;
public class NormalUser extends User{
public NormalUser(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(" 0. 退出系统");
System.out.println("*********************");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的操作:");
int choice = scanner.nextInt();
return choice;
}
}
那么又如何根据返回值,找到是 哪个对象 的 哪个方法 呢?
1、哪个对象
User user = login(); 已经实现了根据用户输入的数字调用不同的对象的方法。
2、哪个方法
前提是确保调用的对象中包含了这些方法,才能被调用。在抽象类中定义接口类数组包含相应的操作。
java
package user;
import ioperation.IOperation;
public abstract class User {
protected String name;
// 接口类数组还没有被初始化,应该交给子类进行初始化
protected IOperation[] iOperations;
public User(String name) {
this.name = name;
}
public abstract int menu();
}
注意在调用子类对象时,构造方法会初始化好对应的操作对象,因此应该将初始化数组的语句写到子类的构造方法里面。
java
package user;
import ioperation.*;
import java.util.Scanner;
public class AdmUser extends User{
public AdmUser(String name) {
super(name);
this.iOperations= new IOperation[]{
new ExitOperation(), // 将选择0退出系统放到数组第一个元素,因为其下标就是0
new FindOperation(),
new AddOperation(),
new DelOperation(),
new ShowOperation(),
};
}
public int menu(){
//System.out.println("欢迎"+ this.name + "来到图书管理系统"); // main方法中传name值到子类,因此可以接收
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("***********************");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的操作:");
int choice = scanner.nextInt();
return choice;
}
}
有一个巧妙的地方就是用户选择0与数组下标0对应,即 ExitOperation 不是根据打印的菜单位置来放的,而是根据数组下标,用户输入0,调用的就是数组下标为0的 ExitOperation 退出操作。
java
package user;
import ioperation.*;
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("******普通用户菜单******");
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);
System.out.println("请输入您的操作:");
int choice = scanner.nextInt();
return choice;
}
}
那么有了操作类的框架,接下是如何通过用户输入的值调用的问题(我们先有框架在最后才具体实现各个操作)。
可以在用户父类中编写一个调用接口方法的方法,通过 User 类调用 doIOperation 的方法,再通过 doIOperation 方法调用 work 方法。
java
package user;
import book.BookList;
import ioperation.IOperation;
public abstract class User {
protected String name;
// 接口类数组还没有被初始化,应该交给子类进行初始化
protected IOperation[] iOperations;
public User(String name) {
this.name = name;
}
public abstract int menu();
public void doIOperation(int choice, BookList bookList){ // 新增这个方法,通过下标访问相应的操作
iOperations[choice].work(bookList); // 此处的 iOperations[choice] 相当于 new xxxOperation() 对象,再通过对象调用该对象中的 work() 方法。
}
}
为什么要在 User 类中新增 doIOpeatrion 方法?因为在前面编写主程序入口时,我们在 main 方法中用的是 User 引用变量 user 来接收,那么当然调用的也是父类中的方法。
java
import book.BookList;
import user.AdmUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
public class Main {
public static User login(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的姓名:");
String n = scanner.nextLine();
System.out.println("欢迎" + n + "来到图书管理系统");
System.out.println("请输入您的身份,1、管理员 2、普通用户");
int choice = scanner.nextInt();
if (choice == 1){
return new AdmUser(n);
}else if (choice == 2){
return new NormalUser(n);
}else {
return null;
}
}
public static void main(String[] args) {
BookList bookList = new BookList(); // 实例化 BookList 对象
User user = login();
assert user != null;
int choice = user.menu();
user.doIOperation(choice,bookList); // 调用操作方法并传参
}
}

七、多次操作
上面的程序运行之后我们发现,用户选择1次操作完成之后系统自动退出了。为了能多次进行操作,应该使用循环语句。此处用 while 条件判断语句为 true。
java
import book.BookList;
import user.AdmUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
public class Main {
public static User login(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的姓名:");
String n = scanner.nextLine();
System.out.println("欢迎" + n + "来到图书管理系统");
System.out.println("请输入您的身份,1、管理员 2、普通用户");
int choice = scanner.nextInt();
if (choice == 1){
return new AdmUser(n);
}else if (choice == 2){
return new NormalUser(n);
}else {
return null;
}
}
public static void main(String[] args) {
BookList bookList = new BookList();
User user = login();
while (true) {
assert user != null;
int choice = user.menu();
user.doIOperation(choice, bookList);
}
}
}
八、程序运行分析
其实整个程序只用4步:

1、实例化书架类(在这一步的同时,初始化好了原有的3本书的信息);
2、调用 login 静态方法,用户输入的名字作为参数传递,根据用户的选择创建相应的对象并用 User 类型的引用变量进行接收;
3、通过引用变量输出菜单并返回用户选择的操作下标;
4、调用 User 类的操作方法。
九、具体实现业务
我们按照实现的难易程度来补充每个操作的具体实现业务,其顺序如下:
退出系统 -> 显示图书 -> 查找图书 -> 新增图书 -> 借阅图书 -> 归还图书 -> 删除图书
9.1 退出系统
java
package ioperation;
import book.BookList;
public class ExitOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("退出系统......");
System.exit(0);
}
}
调用系统的方法,因为一般在IDEA中退出程序之后输出的是 Process finished with exit code 0,所以括号里面的数字放的是0。
9.2 显示图书
显示图书的思路是利用 for 循环遍历书架上存放的图书数组 Book[]:
1、因为存放的数量不一定是10本,遍历次数也没必要是10本,因此需要取得当前存放图书的有效数量,这就是为什么要定义 useSize 变量的原因;而因为 useSize 被 private 修饰无法直接访问,因此要在 BookList 上设置 set 和 get 方法:
java
package book;
public class BookList {
private Book[] books = new Book[10];
private int useSize; // 有效的数据个数【实际存放书本的个数】
public BookList(){
this.books[0] = new Book("三国演义","罗贯中",59.8,"小说");
this.books[1] = new Book("西游记","吴承恩",59.8,"小说");
this.books[2] = new Book("红楼梦","曹雪芹",59.8,"小说");
this.useSize = 3;
}
public int getUseSize() {
return useSize;
}
public void setUseSize(int useSize) {
this.useSize = useSize;
}
}
2、接下来需要获取 books 中的每一本书,因此也需要对成员变量 books 设置 set 和 get 方法,但是我们可以看到由编译器生成的 get 方法返回的是整个数组,与 for 循环要求不符,因此需要修改方法使得每次进入 for 循环只能拿到1本图书(这里的 pos 相当于下标);而 set 设置图书的方法则需要传入 book 对象引用,此方法将在后面的操作中被使用到。
java
package book;
public class BookList {
private Book[] books = new Book[10];
private int useSize; // 有效的数据个数【实际存放书本的个数】
public BookList(){
this.books[0] = new Book("三国演义","罗贯中",59.8,"小说");
this.books[1] = new Book("西游记","吴承恩",59.8,"小说");
this.books[2] = new Book("红楼梦","曹雪芹",59.8,"小说");
this.useSize = 3;
}
public int getUseSize() {
return useSize;
}
public void setUseSize(int useSize) {
this.useSize = useSize;
}
public Book getBook(int pos) { // 每次进入for循环中只想取得目的下标的一本图书
return books[pos];
}
public void setBooks(int pos, Book book) {
this.books[pos] = book;
}
}
3、做完上面的工作之后,可以通过 bookList 引用变量调用获取当前存放图书数量的方法,并使用 for 循环调用 getBook 方法查找书架上的每一本书并打印出来。【此处需要注意的是 bookList 是引用变量,而不是数组,不能直接对下标进行操作】
java
package ioperation;
import book.Book;
import book.BookList;
public class ShowOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("显示图书......");
int currentSize = bookList.getUseSize(); // 获取当前存放图书的个数
for (int i = 0; i < currentSize; i++) {
Book book = bookList.getBook(i);
System.out.println(book);
// Book book = bookList[i]; // 错误的,因为bookList不是数组,而是对象引用
}
}
}

9.3 查找图书
一般是根据书名来查找相应的图书,然后通过标签(放到系统上是下标)对书架进行查找,因此也用到遍历的思想,同时比较书名是否一样要调用什么方法?
java
package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class FindOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("查找图书......");
Scanner scanner = new Scanner(System.in);
System.out.print("请输入书名:");
String name = scanner.nextLine();
int currentSize = bookList.getUseSize();
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; // 找到就返回,work方法结束
}
}
System.out.println("查无此书......"); // 遍历完都没找到,程序就会执行这一行
}
}
9.4 新增图书
新增图书有以下步骤:
1、判断书架是否已满;
此处需要获得图书数组的总长度,因此在 BookList 中需要新增 getBooks() 方法。
2、输入新图书的各种成员变量,构造对象;
3、判断此书是否已存在;
4、放到数组的最后一个位置;
5、有效图书数量加1,即 usedSize++。
java
package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class AddOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("新增图书......");
// 1、判满
int currentSize = bookList.getUseSize();
if (currentSize == bookList.getBooks().length){ // 需要获取数组的总长度,因此 BookList 中需要新增 getBooks() 方法
System.out.println("书架已满,不能新增图书。");
return;
}
// 2、构造对象
Scanner scanner = new Scanner(System.in);
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.nextLine();
Book newBook = new Book(name,author,price,type);
// 3、判断该书是否存在
for (int i = 0; i < currentSize; i++) {
Book book = bookList.getBook(i); // 拿到书架上的书
if (book.getName().equals(name)){ // 核对该书与用户输入的书名是否一样
System.out.println("这本图书已存在,不可插入!");
return; // 找到就返回,不再进入循环
}
}
// 4、插入图书
bookList.setBooks(currentSize, newBook);
bookList.setUseSize(currentSize+1);
System.out.println("成功新增图书。");
}
}
在测试运行时出现下面的问题:还未输入类型就已经成功添加了,原因是输入单价之后的"回车"被当中成符被下一个 scanner.nextLine() 读取。解决方法有两个:1、交换输入单价和输入类型的顺序;2、在输入单价之后新增读取空字符的语句:scanner.nextLine();

9.5 借阅图书
核心思想就是输入书名并查找是否有这本书,若有就直接修改 isBorrow 的值。
java
package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("借阅图书......");
Scanner scanner = new Scanner(System.in);
System.out.print("请输入书名:");
String name = scanner.nextLine();
int currentSize = bookList.getUseSize();
for (int i = 0; i < currentSize; i++) {
Book book = bookList.getBook(i);
if (book.getName().equals(name)){
book.setBorrow(true);
System.out.println("借阅成功");
return;
}
}
System.out.println("查无此书......");
}
}
但是!需要注意如果这本书已经被借出,是无法再次被借到的,因此在借阅之前需要判断一下 isBorrow 的值。
java
package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("借阅图书......");
Scanner scanner = new Scanner(System.in);
System.out.print("请输入您要借阅的书名:");
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)){
if (book.isBorrow()){ // 若为 true 则执行这个语句块
System.out.println("这本书已经被借出!");
return;
}
book.setBorrow(true);
System.out.println("借阅成功");
return;
}
}
System.out.println("查无此书......");
}
}
9.6 删除图书
核心思想是找到目的下标的对象,用下一个对象覆盖该位置的对象。
java
package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class DelOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("删除图书......");
Scanner scanner = new Scanner(System.in);
System.out.print("请输入您要删除的书名:");
String name = scanner.nextLine();
int currentSize = bookList.getUsedSize();
// 查找该书的位置,将下标赋值给 pos
int pos = -1;
int i = 0;
for (; i < currentSize; i++) {
Book book = bookList.getBook(i);
if (book.getName().equals(name)){
pos = i;
break;
}
}
// 没有找到要删除的图书,则结束整个操作
if (i == currentSize){
System.out.println("没有您要删除的图书!");
return;
}
for (int j = pos; j < currentSize-1; j++) { // j的范围是 pos~currentSize-1 ,是为了访问时防止溢出
//bookList[j] = bookList[j+1]; // 按照平时的写法是这样没错,但在这里 bookList 并不是数组
Book book = bookList.getBook(j+1);
bookList.setBooks(j,book);
}
bookList.setBooks(currentSize, null); // 将最后的对象置空,也可以省略这一步,因为下一条语句使得后续操作无法获取这个对象
bookList.setUsedSize(currentSize-1);
System.out.println("删除成功!");
}
}
十、可扩展
本文中的管理系统应用的是非常基础的知识,若后续学习了更多的知识,将有机会从下面几个方向进行拓展:
1、每次运行程序,上次操作之后的结果,比如新增了的图书没有了。所以想要存储数据,有以下几个思路:
①将数据存储到文件当中,即磁盘上。涉及文件的读取(IO流)知识在JavaEE初阶上;
②存储到数据库 MySQL 中,也是相当于存储到磁盘里,在每次运行程序读取数据库即可。
2、后续学完 EE 初阶的知识,也可以将该项目实现为 WEB 端的一个小练习;需要加入网页和加入框架。
3、也可以扩展一些功能,如
①令书按照书名排序
②令书按照价格排序
③令书按照作者名排序