在前面的十三课中,笔者已经介绍了有关java的各种语法及其细节。若要融会贯通,则还需大量的练习,而非单纯的依赖于笔记中的内容。毕竟“纸上得来终觉浅,绝知此事要躬行”。在java语法的最后一节内容,我将运用之前学到的所有内容,实现一个简单的图书管理系统,并力将整个项目的实现细节讲解到位,共同学习。话不多说,进入正题。

         首先,我会展示项目的最终实现效果:

一:管理员层面

 

二:用户层面

 

实现一个图书馆里系统,要包含以下三大块内容:

1.书包,要有每本书的信息,同时还要把每本书存放起来。即对于书的细节和一本书的存放情况,分别进行实现。于是就有了我们的第一个包:

2. 操作包:图书管理系统,其核心就是对书籍进行存取管理,这里同时又涉及到操作者的身份。操作者身份不同,则可以进行的操作也有所差异。这里先抽象出一个操作包,用于存放可能进行的操作。

3.正如2中所提到的,我们的第三个包,就是用于区分不同操作者的。

结合我们之前的思考,最后整体的结构如下图所示:

需要说明的是,在实际开发过程中,我们很难一次性想到所有需要实现的功能,通常会根据编写程序的进度及过程中出现的问题,不断改进、完善每个文件中的具体内容。但为使文章的思路更加流程,也为了减小书写的难度,我的行文思路是:在打好框架的基础上,尽量按照上图中从上到下的顺序,进行拆分讲解。

book.class

package book;public class Book {public String name;String author;double price;String type;boolean isBorrowed;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 isBorrowed() {return isBorrowed;}public void setBorrowed(boolean borrowed) {isBorrowed = borrowed;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +", type='" + type + '\'' +",status=" +((isBorrowed==true)?"已借出":"未借出") +'}';}
}

这个类非常简单,就是一个书类,包含了书名、作者、价格、类型、在借状态这5个private成员,并提供Getter And Setter方法实现访问;提供了一个带四个参数的构造方法,最后重写toString方法。唯一需要注意的是,我们并没有将status参数放在构造方法中进行初始化,因为当你添加一本书时,默认是未借出的,即status=false,而这正是status这个变量的默认值,无需进行手动传参的设置。

BookList.class

package book;//BookList是书架,Book是书,实例化一书架booklist,实例化书book,booklist数组中上放的是book元素
public class BookList {private Book books[]=new Book[10];private int usedSize;public BookList(){books[0]=new Book("三国演义","罗贯中",25.8,"名著");books[1]=new Book("百年孤独","马尔克斯",54.5,"文学");books[2]=new Book("卡片笔记写作法","阿伦斯",23.3,"工具");usedSize = 3;}public int getUsedSize() {return usedSize;}public void setUsedSize(int usedSize) {this.usedSize = usedSize;}//获取某个下标的书public Book getPos(int pos){return books[pos];}//给数组的pos位置放一本书public void setBooks(int pos,Book book){books[pos]=book;}
}

如你所见,这是一个书架类。一开头我们就定义了一个book[]数组,用于存放书的信息,当然数组中每个成员都是Book类型的。通过构造方法,我先将三本书放入了“书架”。

usedSize用于显示当前书架中书的数目,我当然会为它提供Getter And Setter方法,以方便的获取和修改usedSize的值,及时更新数据。

如果你有一定的预见性,可能会想到我们需要做这样的事件,就是在书架的任意位置存放一本书,所以我们提供了setBooks方法,其参数为pos位置和一本书对象book。

IOPeration.class


import book.BookList;public interface IOPeration {public void work(BookList bookList);}

这是一项独特的设计,既然我们要实现多个对书架的操作,我们索性实现一个操作接口,再让所有的操作实现这个接口,并重写其中的work()方法。参数自然是整个书架bookList。

对于每个操作的具体实现,我会在后文进行讲解。

User.class

package users;
import book.BookList;
import operation.IOPeration;
public abstract class User {protected String name;public User(String name) {this.name = name;}public IOPeration[] ioPerations;//一个接口数组public abstract int menu();//如何得知调用哪个方法?public void doOperation(int choice, BookList booklist){ioPerations[choice].work(booklist);//数组的某个下标是对象,可以调用对象的work()方法。}
}

首先,User中的方法无需具体实现,所以我们会将其设置为abstract抽象类,其中的方法也定义为抽象方法。管理员和用户拥有共同的属性姓名,定义为name并使用构造方法进行初始化(具体到子类自然要重写父类的构造方法)。

我们先来看看最后实现出来的功能菜单:

我们期望的是从键盘上输入各个操作所对应的数字,就可以调用相对应的方法。那么如何知道调用哪个方法呢?这就要使用到接口数组,将所有的操作放在一个接口数组ioPerations中,每个操作自然会对应数组的下标,通过下标就可以找到这个操作类,再调用这个类下的work()方法。

如果对这里不理解,不妨回忆一下我们在第十一课——抽象类与接口一文中所讲过的这个例子:(理解的朋友可以直接跳过)

ADdminUser

package users;import book.BookList;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 DisplayOperation()};}//重写父类抽象方法@Overridepublic int menu() {System.out.println("===========管理员菜单==========");System.out.println("您好 "+this.name+" 欢迎来到世界联合图书馆");System.out.println("1.查找图书");System.out.println("2.新增图书");System.out.println("3.删除图书");System.out.println("4.显示图书");System.out.println("0.退出系统");System.out.println("请输入你的操作:");Scanner sc = new Scanner(System.in);int choice = sc.nextInt();return choice;}
}

这是对于管理者的具体实现。首先,重写父类构造方法;第二步,创建接口数组,放入管理员可以进行的操作;最后,重写父类中的抽象方法menu()。需要注意是,数组的下标与操作要相互对应,所以我们将ExitOperation()放在数组的第一个位置,确保输入0时正常退出系统。

NormalUser.class

package users;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 BorrowOperation(),new ReturnOperation()};}@Overridepublic int menu() {System.out.println("===========用户菜单==========");System.out.println("您好 "+this.name+" 欢迎来到世界联合图书馆");System.out.println("1.查找图书");System.out.println("2.借阅图书");System.out.println("3.归还图书");System.out.println("0.退出系统");System.out.println("请输入你的操作:");Scanner sc = new Scanner(System.in);int choice = sc.nextInt();return choice;}
}

这是对于普通用户的具体实现。与管理员的唯一不同之处在于接口数组,因为它他们会进行不同的操作。

Main.class

import book.BookList;
import users.AdminUser;
import users.NormalUser;
import users.User;import java.util.Scanner;public class Main {public static User login(){System.out.println("请输入您的姓名:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();System.out.println("请输入你的身份:1->管理员  0->用户");int choice =sc.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();while(true){int choice = user.menu();user.doOperation(choice,bookList);}}}

在主函数的实现中,我们需要考虑一个非常重要的问题,就是如何得知当前正在使用该系统的人是管理员还是普通用户呢?所以我们设置登陆选项,根据使用者的输入确定其身份,不同的身份,会打印不同的菜单,也会实现不同的操作。父类引用引用子类对象,在这里用到了“继承”的知识,根据返回值的不同,当前用户的身份也可以得到确认了。

根据我们的思考,在main函数中实例化出书架bookList和用户User对象即可。为实现多次输入,我们操作的具体实现放在while(true)循环中,并通过退出系统的类实现循环终止。

至此,我们整体的实现逻辑已经言明。接下来,我会展示每一个操作的代码,需要注意的是,所有的操作都实现了IOPeration接口,并重写其中的work()方法。

AddOperation.class(新增图书)

package operation;import book.Book;
import book.BookList;import java.util.Scanner;public class AddOperation implements IOPeration{public void work(BookList bookList){System.out.println("新增图书!");int currentSize = bookList.getUsedSize();System.out.println("请输入你要添加的图书的信息:");Scanner sc = new Scanner(System.in) ;System.out.println("请输入书名");String name = sc.nextLine();System.out.println("请输入作者");String author = sc.nextLine();System.out.println("请输入类型");String type = sc.nextLine();System.out.println("请输入价格");double price = sc.nextDouble();Book book = new Book(name,author,price,type);bookList.setBooks(currentSize,book);bookList.setUsedSize(currentSize+1);System.out.println("添加成功!");}
}

首先输入你要新增书目的所有信息,然后将这些信息作为参数实例化book,基于预见性,我们已经在BookList类中实现了在某个位置插入一本书的函数setBooks(),直接调用即可,最后别忘记通过setUsedSize()方法将书的数目+1。

BorrowOperation.class

package operation;import book.Book;
import book.BookList;import java.util.Scanner;public class BorrowOperation implements IOPeration{public void work(BookList bookList){System.out.println("借阅图书!");System.out.println("请输入你要借阅的图书的名字:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();int currentSize = bookList.getUsedSize();for (int i = 0; i <currentSize ; i++) {Book book = bookList.getPos(i);if(book.getName().equals(name)&&book.isBorrowed()==false){System.out.println("借阅成功");book.setBorrowed(true);bookList.setUsedSize(--currentSize);return;}else if(book.getName().equals(name)&&book.isBorrowed()==true){System.out.println("该书已被借出");return;}else{System.out.println("该书不存在!");return;}}}Scanner sc = new Scanner(System.in);
}

对于借书,我们的思路是输入书名,然后遍历书架数组,进行书名匹配。如果循环结束任未匹配成功,那么说明“该书不存在”;如果书名匹配成功并且借阅状态为“已借出”,那么说明该书存在但已经被借出,无法借阅;当且仅当书名匹配成功并且借阅状态为“未借出”时,才能进行借书。而借阅成功,需要将其借阅状态改为“已借出”,并将书目数减1。也有人认为此时应该直接将这本书的信息删去,不应该是只改变在借状态,这与每个人对项目的理解不同,你当然可以根据自己的想法进行业务拓展或改进。

DelOperation.class

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("删除图书!");System.out.println("请输入你要删除的书名:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {Book book = bookList.getPos(i);if (book.getName().equals(name)) {for (int j = i; j < currentSize; j++) {book = bookList.getPos(j + 1);bookList.setBooks(j, book);}System.out.println("删除成功!");bookList.setUsedSize(--currentSize);return;}}System.out.println("该书不存在!");}}

如果要删除一本书,首先输入欲删除书的书名,然后遍历书架数组,进行书名匹配。如果匹配失败,那么自然无法进行删除;匹配成功时,可以进行删除。与在整型数组中删除元素的思路类似,删除书架数组任意位置的元素同样采用覆盖的方式。从你要删除的那本书开始进行循环,依次让后一本书覆盖前一本书(即设置前一本书的内容为后一本书,同样用到setBooks()函数)。删除成功之后,将书目数减1。

DisplayOperationy.class

package operation;import book.Book;
import book.BookList;public class DisplayOperation implements IOPeration{public void work(BookList bookList){System.out.println("显示图书!");int currentSize = bookList.getUsedSize();for (int i = 0; i <currentSize ; i++) {Book book = bookList.getPos(i);System.out.println(book);}}}

显示图书,就是打印每一本书的信息。直接循环遍历书架数组,调用toString()方法打印每本书的信息即可。

ExitOperation.class

package operation;import book.BookList;public class ExitOperation implements IOPeration{public void work(BookList bookList){System.out.println("退出系统!");int currentSize = bookList.getUsedSize();for (int i = 0; i <currentSize ; i++) {bookList.setBooks(i,null);}System.exit(0);}
}

退出系统。当我们退出系统时,自然需要将书架中的内容情况,即循环遍历书架数组,将每一个位置上的元素置为NULL。System.exit(0)可以终止当前程序的运行,退出系统。

FindOperation.class

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 sc = new Scanner(System.in);String name = sc.nextLine();int currentSize = bookList.getUsedSize();for (int i = 0; i <currentSize ; i++) {Book book = bookList.getPos(i);if(book.getName().equals(name)){System.out.println("找到了,信息如下:");System.out.println(book);return;}}System.out.println("该书不存在!");}
}

查找图书。输入你要查找的书名,并在书架数组中进行遍历匹配,如果匹配成功,说明该书存在,直接打印这本书的信息即可;如果匹配失败,则返回“该书不存在”。

ReturnOperation.class

package operation;import book.Book;
import book.BookList;import java.util.Scanner;public class ReturnOperation implements IOPeration{public void work(BookList bookList){System.out.println("归还图书!");System.out.println("请输入你要归还的图书的名字:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();int currentSize = bookList.getUsedSize();for (int i = 0; i <currentSize ; i++) {Book book = bookList.getPos(i);if(book.getName().equals(name)&&book.isBorrowed()==true){System.out.println("归还成功");book.setBorrowed(false);bookList.setUsedSize(++currentSize);return;}else if(book.getName().equals(name)&&book.isBorrowed()==false){System.out.println("该书不属于在借图书!");return;}}System.out.println("非本馆图书!");}}

归还图书。先输入你要归还的图书的书名,然后在书架数组中进行遍历匹配。一种情况是没有匹配成功,那说明这不是本馆的图书,直接打印“非本馆图书!”;在匹配成功的情况下,如果该书的借阅状态为“已借出”,那么可以进行归还,将其借阅状态设置为“未借出”,并将usedSize加1即可。如果你已经理解了这波操作,这也是为什么在借出图书时,我仅仅修改了图书的借阅状态,而没有直接将图书信息全部删除的原因。


至此,整个图书管理系统已经实现完毕,并且笔者也已经在文章开头进行过效果的演示。

这篇博客落幕,java基础语法的内容也已更新完毕了。虽然读者很少,我仍坚信这些文章的价值,也不会去怀疑书写这些文章的意义。即使无人问津,我们还是要去写;即使没有外界的正反馈,我们依然要遵从自己内心的声音,依然要相信坚持的力量。与诸君共勉!


本课内容结束!

java初级内容结课项目——图书管理系统相关推荐

  1. Java+JSP+Mysql+Tomcat实现Web图书管理系统

    图书管理系统 一.系统介绍 1.软件环境 2.功能模块图 3.系统功能 4.数据库表 5.工程截图 二.系统展示 1.系统注册 2.系统登录 3.找回密码 4.管理员-主页 5.管理员-用户管理主页 ...

  2. Github 精选开源项目-图书管理系统

    Github 精选开源项目-图书管理系统 项目是一款图书管理系统[Book-manager],适用于大学生实训的图书管理系统,这是一个非常精简化的图书管理系统,可拓展性高,集成主流框架. 首先放出Gi ...

  3. Java项目:图书管理系统(java+JSP+layui+bootstrap+Servlet+Mysql)

    源码获取:俺的博客首页 "资源" 里下载! 项目介绍 使用jsp+servlet.layui.mysql完成的图书馆系统,包含用户图书借阅.图书管理员.系统管理员界面,功能齐全. ...

  4. Java——课设——图书管理系统实现 2.0

    Java--图书管理系统 系统简介 1.本系统存有书籍信息与管理员.用户账号.管理员与用户(教师.学生)可以使用本系统. 2.系统数据存有以学号.工号为编号的空账号,用户可以输入工号.学号进行注册,管 ...

  5. Java项目:图书管理系统(java+SSM+jsp+mysql+maven)

    源码获取:博客首页 "资源" 里下载! 一.项目简述 功能包括(管理员和学生角色): 管理员和学生登录,图书管理,图书添加删除修改,图书 借阅,图书归还,图书查看,学生管理,借还管 ...

  6. java小项目图书管理系统_Java小项目迷你图书管理系统

    package迷你图书管理系统;importjava.util.Scanner;public classBookMgr {public static voidmain(String[] args) { ...

  7. C++期末课设—图书管理系统

    期末将至,还有人为不知道如何写课设而头疼吗,这里给大家带来一个最简单基础的课设项目,图书管理系统. 功能分析 一般来说,简单的图书管理系统有以下几个功能: 1.用户管理 2.读者管理 3.图书管理 4 ...

  8. 第一个C语言项目——图书管理系统

    [文末获取源码] 该系统是我们C语言课上的一个作业,本来是不打算写的,但是找了好久都没有找到心仪的代码,所以被迫写了该系统,该图书管理系统一共有十个功能,具体如下说明: 01.注册账号 02.登录账号 ...

  9. 开源项目-图书管理系统

    哈喽,大家好,今天给大家带来一个图书管理系统 系统主要分为图书管理,读者管理,借还管理等模块,可以下载源码了解详情 项目简介 本图书管理系统基于spring,spring mvc,数据库为mysql. ...

最新文章

  1. 并查集c++代码_[Leetcode 每日精选](本周主题-并查集) 547. 朋友圈
  2. android用java_原来android不是只能用java写软件
  3. 基于DM8168 EVM的智能视频跟踪系统
  4. oracle查询表的索引
  5. 【数字信号处理】傅里叶变换性质 ( 傅里叶变换频移性质示例 )
  6. 【.NET Core项目实战-统一认证平台】第三章 网关篇-数据库存储配置(1)
  7. php遍历视频文件,php使用glob函数遍历文件和目录详解
  8. 配置信息的优化,类型转换器
  9. @程序员,不要瞎努力!比起熬夜更可怕的是“熬日”!
  10. 【网络】c++ socket 学习笔记(一)
  11. html5游戏制作入门系列教程(三)
  12. crash分析 (如何确定主进程死掉的点)
  13. 线段树详解 二 ----(区间修改区间查询)
  14. 给自己一个anchor,挑战不可能
  15. BNU 斩(超级大水题)
  16. 爬虫(二)—解析真实网页(猫途鹰)
  17. IDEA颜色及主题配色方案记录,持续更新中。。。
  18. java实现节假日维护_谈谈JAVA实现节假日验证
  19. gwas snp 和_GWAS综述(生信文献阅读俱乐部精选)
  20. CRISPR最新:新CRISPR技术靶向更复杂的人类基因组代码

热门文章

  1. flutter和原生交互
  2. Python:元组和字典简述
  3. Ansoft Maxwell学习
  4. https://blog.csdn.net/zhi_sheng/article/details/78910082----mybatis写当天 当月的数据 时间段数据...
  5. 2022世界传感器大会 | 龙芯中科发布龙芯2K0500多功能SoC芯片及解决方案
  6. 滴答顺风车怎么抢90%以上的订单_顺风车这样做才是对的,其他都是扯淡!
  7. 静态路由的基本原理讲解
  8. 谷歌插件开发(实现CSDN快速登陆)
  9. 专业水平自述 计算机,研究生个人陈述范例,计算机专业.
  10. linux下的tar压缩解压缩命令详解,Linux下的tar压缩解压缩命令详解