【JavaSE】图书管理系统(语法综合练习,有思考过程)

》》》我的博客主页
》》》我的gitee链接
关注我,在学习Java的道路上共同进步!!!

Alt



前言

目标: 通过实现图书管理系统 巩固JavaSE语法基础 , 没有涉及数据库和网页交互的实现内容。
IDE:IntelliJ IDEA Community Edition 2022.3.3

对 代码实现的思考 和 实现步骤

不管要实现什么,面向对象编程都要经历3个步骤:

  1. 找到对象
  2. 创建对象
  3. 使用对象

接下来对这三个步骤一一分析,展现从 0 到完整实现的思考过程。

1. 找到对象

分析需求: 既然要实现图书管理系统,我们需要考虑哪些 对象

  • 书本:书本这个对象要有书名,作者,价格,分区,是否借出的信息
  • 书架:存放书本的地方
  • 普通用户:对图书借阅和归还的用户
  • 管理员用户:管理图书的用户
  • 普通用户的操作(查找图书,借书,还书,退出图书管理系统)
  • 管理员用户的操作(显示图书,查找图书,新增图书,删除图书,退出图书管理系统)

2. 创建对象

我们已经分析了图书管理系统大致需要实现哪些对象,
接下来创建对象时需要 先 定义类 再进行 对象的实例化

为了更好的管理和使用类,我们先自定义包:

  • 书本 和 书架 的类都放进 book 包
  • 普通用户 和 管理员用户 都放进 user 包
  • 普通用户的操作 和 管理员用户的操作 都放进 operation 包

Alt

接着分别在每一个包中定义好类:

book包中的书本类

需要定义 书名,作者,价格,分区,是否借出的信息 的成员变量,而且需要被private修饰增加数据的封装性。
然后快速生成 构造方法,getter and setter 方法 和 重写的 toString() 方法。
快速生成的步骤:
鼠标右击 --》选中 Generate --》选中 Constructor (getter and setter 和 toString 方法同理) --》
然后根据需求选择 (按住Shift键可多选),点击OK即可。
Alt
Alt
因为Book类当中的 isBookBorrowed 默认是 false,也就是未被借出的状态,所以创建构造方法的时候无需添加 isBookBorrowed 参数。
Alt
getter and setter 方法直接全部生成即可。

要重写 toString() 方法是因为我们要查看一本书的信息时,直接 System.out.println(要打印出信息的书本对象名); 即可,如果没有重写 toString() 方法只会打印出该对象的引用。
Alt

我希望最后可以显示 已被借出 或者 未被借出 的信息,而不是显示 true 或 false 的信息,可以对 toString() 方法稍作修改:
Alt

书本的类定义完成,接下来是

book包中的书架类

我们可以用数组模拟书架,这个数组中的每一个元素都是一个Book对象。
所以我们可以在书架类当中定义一个成员变量 Book[ ] 类型的对象数组 books,书本从对象数组的下标 0 开始按顺序存放。
我们可能还需要知道在这个对象数组中已经存放了多少本书,所以再定义一个成员变量 int 类型的 usedSize
还需要知道这个书架的容量,我们可以提前设置好这个书架的默认容量,且在编译运行的时候不能改动这个容量。
Alt

接着可以通过构造方法对书架类的成员变量进行初始化:
Alt
接着,我们可能需要在书架上找出某一本书 或者 要放进一本书,可以实现 getBook方法 和 setBook方法:
Alt
我们新增图书的话,书架上的书的数目就会增加,所以要提供 getUsedSize 和setUsedSize 方法(快速生成即可):
Alt
因为我们用构造方法对 对象数组 进行初始化了,无需再对整个书架进行设置,所以可能只需用到 getBooks 方法:
Alt

此时我们已经在书架类中把可能会用到的方法都写好了。
到此为止,book包中的 Book类 和 BookList类 基本都定义好了,接下来要定义

operation 包当中的所有操作类

我们先罗列 普通用户 和 管理员用户 中之前分析的所有操作:
普通用户的操作:查找图书,借书,还书,退出图书管理系统。
管理员用户的操作:显示图书,查找图书,新增图书,删除图书,退出图书管理系统。

所以我们总共要实现 7 个操作:

  1. 显示图书
  2. 查找图书
  3. 新增图书
  4. 删除图书
  5. 借书
  6. 还书
  7. 退出图书管理系统

观察这7个操作的共同行为,我们可以发现:
除了退出管理系统以外,每个操作都需要与 书架 这个对象进行交互:

  • 显示图书需要 通过书架对象 获得所有图书的信息,
  • 新增图书需要 通过访问书架对象 的某个位置进行图书的添加,
  • 借书需要 通过访问书架对象 中的某一本书的信息改成 “已被借出”…

因此,我们可以通过这些操作的共同行为 定义一个接口,对操作进行抽象化:
Alt
然后让每个不同的操作类实现这个接口,具体的实现过程先不写:
Alt
其他操作类的定义同理。
Alt
先不谈每个用户操作的具体实现,我们已经定义好了 operation包中的所有类。
接下来就是在 user包 当中定义
管理员用户的类 和 普通用户的类

普通用户 和 管理员用户 都是用户,可以先定义一个用户的 抽象类
普通用户 和 管理员用户 都有对应的不同的操作,怎么区分哪些是 普通用户的操作,哪些是 管理员用户的操作?

就像 Book [ ] 类型的对象数组中的每个元素都可以是一个不同的书本对象,我们也可以定义一个对象数组,让该数组中的每一个元素都存不同的操作对象,然后仅仅通过下标访问,就能实现该用户想要执行的操作。

因此,我们可以在用户抽象类当中定义一个 IOperation[ ] 类型的对象数组 (因为具体的各个操作类实现了IOperation接口,所以类型不冲突),当管理员用户类 和 普通用户类 继承了 用户抽象类的时候, 子类用户就能初始化这个对象数组并把 子类用户的操作一一赋值给这个对象数组的某个下标位置。
Alt
Alt

此时注意到一个问题:

  • 即使退出管理系统的操作不会与书架这个对象进行交互,但我们也要在 ExitOperation 实现 IOperation接口 并且 重写 IOperation接口 中的 work方法。
    Alt

管理员用户 和 普通用户 分别需要不同的菜单选项,所以用户抽象类需要定义一个抽象的菜单方法,子类用户才能根据不同用户的情况重写不同的菜单方法。
Alt
无论是普通用户 还是 管理员用户,用户根据菜单选择他想操作的功能,我们需要通过特定的下标调用该用户对象的 iOperations 数组中的操作对象 当中的work方法。
因为这个是 普通用户 还是 管理员用户 可以共有的方法,所以我们写在User类中。
Alt

当用户输完名字并且确认完自己的身份 (普通用户/管理员用户) 时,我们需要实例化一个 (普通用户/管理员用户) 对象并且可以传入名字这个参数,那么,User类需要有一个带有name参数的构造方法对该对象的name进行初始化。

Alt
此时,父类定义完成,该定义 管理员用户类 和 普通用户类 了。

构造子类时需要先帮助父类进行构造,然后才可以初始化子类对象,也就是初始化 iOperation对象数组,除此之外还要实现菜单方法:
Alt

上面是管理员用户的,下面是普通用户的。
Alt

至此,大致框架已经形成,有些类还没有具体实现,有些类还需要微调,这需要在使用对象的过程中不断调整。
Alt

3. 使用对象

现在单独创建一个 Main类,里面写一个 main方法,让整个图书管理系统的流程从用户登录开始,用户登入在Main类单独写一个 login() 方法实现。
在 login() 方法中,首先要让用户输入姓名,然后要让用户选择自己的身份,如果是管理员用户 就返回 一个 管理员用户对象,如果是普通用户 就返回一个 普通用户对象。
Alt

接着可以调用该用户类的菜单,让用户输入选择哪个操作。因为我们之前还没有实现让用户输入选择哪个操作,我们可以对 各个用户类的菜单方法中 进行修改。
Alt
Alt

子类的返回类型修改了,父类中menu抽象方法的返回类型也要修改
Alt

然后我们可以根据从menu方法中返回的用户选择,执行对应的操作程序:
Alt
发现我们之前在 User 类当中定义的 doOperation方法当中需要书架对象,那么我们在用户登录之前直接初始化一个书架对象。
Alt

此时我们可以运行程序看看效果:
Alt

用户想要多次操作的话,加个循环即可。
Alt
现在只需要完成 逐个操作的功能 就能基本实现图书管理系统了,操作方法的具体实现我只用画图和文字的形式说明思路。根据自己想要的业务需求实现即可,这里只是一个参考思路。

  • 借书:让用户输入要借的书名,然后遍历 bookList对象数组,把每本书的书名与用户输入的书名进行比较,如果书名一样,就把这本书的 isBookBorrowed 改成 true 即可。
  • 还书:与借书类似,让用户输入要还的书名,然后遍历 bookList对象数组,把每本书的书名与用户输入的书名进行比较,如果书名一样,就把这本书的 isBookBorrowed 改成 false 即可。
  • 退出管理系统:这个直接上代码:
    Alt
  • 查找图书:让用户输入书名,然后遍历 bookList对象数组,把每本书的书名与用户输入的书名进行比较,如果书名一样,就把这本书的所有信息打印出来,没有就输出没有找到。
  • 显示图书:直接遍历 bookList对象数组,把每本书的信息分别打印出来。
  • 新增图书:新增图书要考虑的事情比较多。首先让用户输入这本书的所有信息 (书名,作者,价格,种类体裁) ,然后遍历 bookList对象数组,需要判断书架上有没有这本书,然后考虑书架放满书了没,没有放满书就在 下标 [当前书的数目] 的位置下新增图书,最后一定不要忘记:新增图书完,书的数目要加1
  • 删除图书:让用户输入要删除的图书,然后遍历 bookList对象数组查找是否有这本书,如果有,就可以按如下图步骤所示实现删除图书:
    Alt
    如果要删除西游记这本书,而西游记这本书通过遍历 bookList对象数组
    假设 发现下标1的引用指向的就是西游记这个书本对象:
    Alt
    如果要删除西游记,对象引用从后往前覆盖即可
    Alt
    Alt

最后要将最后一本书的位置进行 置空 并且 此时书的数目要减1。
Alt
所有的参考代码在下方的完整代码中查看。

完整代码

点击这里查看完整代码

如果你觉得我哪里说的不对或者哪些方面做的不好都可以在评论区提出来,我会虚心接受并对文章质量进行改善,感谢!


猜你喜欢

转载自blog.csdn.net/weixin_73276255/article/details/132776283