当前位置: 首页 > news >正文

【项目】图书管理系统

目录

前言:

项目要求:

知识储备:

代码实现:

Main:

Books包:

Book:

BookList:

Operate包:

Operate:

addOperate:

deleteOperate:

exitOperate:

findOperate:

showOperate:

Persion包:

User: 

Admin:

Reader:


前言:

随着javaSE的学习深入,我们已经明白了什么是类和对象,学会了继承和多态,抽象类和接口,那么我们就可以利用以上几个知识点来完成一个小项目图书管理系统来检验一下我们学习的成果,我们主要完成其框架和一些基本点(起到复习作用,不是为了业务)。

项目要求:

实现一个图书管理系统,有两个用户,普通用户和管理员,两个用户的业务不一样,实现其业务,书有书名,作者,价格,书的类型,是否被借出。

普通用户:0.退出系统 1.查找图书 2.借阅图书 3.归还图书 

管理员用户:0.推出系统 1.查找图书 2.新增图书 3.删除图书 4.显示图书

知识储备:

java基本语法,类和对象,继承和多态,抽象类和接口。

具体效果如下动图所示。

代码实现:

为了培养优良的代码风格,我们将各个模块区分开来,故我们需要创建3个包(有关包如果不太了解的话可以看看封装和包)分别是Books和Operate,Person,功能和其的英文名一样,最后用一个Main类把他们串在一起。

Main:

动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体 调用那个类的方法.

先创建一个书架BookList(具体代码后续给出,重要的是思路),User是Admin(管理员)和Reader(普通用户)的父类,使用User来接受这是因为在代码编译的时候程序并不知道是普通用户还是管理员,只有在我们输入后才确定下来(动态绑定),发生向上转型。用一个while来实现循环输入,因为两个用户的菜单不一样,故我们可以在User中定义一个抽象方法,在两个具体子类中实现,放回的k即为我们的选择操作。user.doOperate(books,k)是我觉的这个项目最精彩的地方,这里先简单理解为调用user,对books进行第k个操作,具体我会在Operate部分详细解释。

import Person.*;
import java.util.Scanner;
import Books.*;public class Main {private static User Logon(){Scanner scanner = new Scanner(System.in);System.out.print("请输入你的姓名: ");String name = scanner.next();System.out.print("请输入你的身份: 1: 管理员   2: 普通用户-> : ");int index = scanner.nextInt();if(index == 1){return new Admin(name);}else if(index == 2){return new Reader(name);}else{System.out.println("输入错误");System.exit(0);return null;}}public static void main(String[] args) {BookList books = new BookList();User user = Logon();//动态绑定while(true){int k = user.menu();user.doOperate(books,k);}}
}

Books包:

在Books包中存储这两个类Book类中存储书的一般属性,BookList就是书架。

Book:

为了更加安全和代码的封装性我们把变量用private修饰,在下面用set和get方法来进行修改。构造方法不用构造isBorrowed因为没有初始化的话java默认为false。

package Books;/*** 书的基本参数*/
public class Book {private String name;private String author;private int price;private String type;//书的类型private boolean isBorrowed;//是否被借出  默认值是falsepublic 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;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +", type='" + type + '\'' +", isBorrowed=" + ((isBorrowed == false) ? "未借出" : "已借阅") +//不确定加括号'}';}
}

要想使用println来直接打印Book的话必须要重写toString方法,下图是println的源码,在valueof中有obj.toStirng的参数,我们基本类型的toString系统已经实现,Book为我们自己定义的一个类所以要自己实现一下。

BookList:

书架上不仅要能放书还要能记录书本的个数,一开始直接初始化3本书方便我们后续调试。

package Books;/*** 书架*/
public class BookList {private Book[] books;//能放书private int BookSize;//记录书本的个数public BookList() {books = new Book[10];this.books[0] = new Book("三国演义","罗贯中",10,"小说");this.books[1] = new Book("西游记","吴承恩",9,"小说");this.books[2] = new Book("红楼梦","曹雪芹",19,"小说");this.BookSize = 3;}public Book[] getBooks() {return books;}public void setBooks(int index,Book books) {this.books[index] = books;}public int getBookSize() {return BookSize;}public void setBookSize(int bookSize) {BookSize = bookSize;}
}

Operate包:

Operate:

这里不是包是一个接口,因为每个操作都只要实现work功能故我们定义一个接口来规范我们的代码,方便后面进行向上转型,work前面可以不用加public abstract系统默认会给你加上

package Operate;
import Books.*;public interface Operate {void work(BookList books);
}

addOperate:

由于本项目难点并不在业务的实现,主要集中在一个框架,故下面的借阅图书和归还图书就由读者自行实现(很简单的)。

package Operate;
import Books.*;
import java.util.*;public class addOperate implements Operate {@Overridepublic void work(BookList books) {Scanner scanner = new Scanner(System.in);System.out.println("请输入书名: ");String name = scanner.next();System.out.println("请输入作者: ");String author = scanner.next();System.out.println("请输入价格: ");int price = scanner.nextInt();System.out.println("请输入书的类型: ");String type = scanner.next();Book book = new Book(name,author,price,type);int usedSize = books.getBookSize();books.setBooks(usedSize,book);books.setBookSize(usedSize + 1);System.out.println("添加成功");System.out.println();}
}

deleteOperate:

package Operate;
import Books.*;
import java.util.Scanner;
public class deleteOperate implements Operate {public void work(BookList books){Scanner scanner = new Scanner(System.in);System.out.print("请输入你要删除书的书名: ");String name = scanner.next();Book[] book = books.getBooks();//浅拷贝int bookSize = books.getBookSize();for(int i = 0;i < bookSize;i++){if(name.equals(book[i].getName())){for(int j = i;j < bookSize - 1;j++){book[j] = book[j + 1];}book[bookSize - 1] = null;System.out.println("删除成功");System.out.println();books.setBookSize(bookSize - 1);return;}}System.out.println("该图书不存在,删除失败");System.out.println();}
}

exitOperate:

package Operate;
import Books.BookList;
public class exitOperate implements Operate{@Overridepublic void work(BookList books) {System.out.println("退出系统");System.exit(0);}
}

 

findOperate:

package Operate;
import Books.BookList;
import Books.Book;
import java.util.Scanner;
public class findOperate implements Operate {@Overridepublic void work(BookList books) {Scanner scanner = new Scanner(System.in);System.out.print("请输入你要查找书的名字: ");String name = scanner.next();Book[] book = books.getBooks();int usedSize = books.getBookSize();for(int i = 0;i < usedSize;i++){if(name.equals(book[i].getName())){System.out.println("找到了,信息如下: ");System.out.println(book[i]);System.out.println();return;}}System.out.println("该图书不存在");System.out.println();}
}

showOperate:

package Operate;
import Books.BookList;
import Books.Book;
public class showOperate implements Operate{@Overridepublic void work(BookList books) {int usedSize = books.getBookSize();Book[] book = books.getBooks();for(int i = 0;i < usedSize;i++){System.out.println(book[i]);}System.out.println();}
}

Persion包:

User是Admin和Reader的父类。

User: 

用一个Operate[]的数组来存储我们上面实现的方法类,因为两个用户对于的方法是不一样的故使用Operate放在User中那个用户需要哪个方法直接new一个方法类在该数组中(向上转型),要调用的时候通过下标访问即可。因为菜单要根据具体是那个用户来具体实现故要把它抽象就可以不用实现,故我们要把User定义成抽象类。

package Person;
import Operate.*;
import Books.*;
public abstract class User {protected String name;protected Operate[] operates;public void doOperate(BookList books,int choice){operates[choice].work(books);}public User(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public abstract int menu();//菜单
}

Admin:

利用super来调用父类的构造方法,在operates中需要什么方法类就直接new上那个方法类,需要注意的是下标的映射关系。继承一个抽象类其子类必须要重写抽象方法。

package Person;
import Operate.*;
import java.util.Scanner;
public class Admin extends User{public Admin(String name){super(name);this.operates = new Operate[]{new exitOperate(),new findOperate(),new addOperate(),new deleteOperate(),new showOperate()};}@Overridepublic int menu() {Scanner scanner = new Scanner(System.in);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.print("请输入你的操作: ");int index = scanner.nextInt();return index;}
}

Reader:

和上面的Admin一样这里就不再赘述。

package Person;
import java.util.Scanner;
import Operate.*;
public class Reader extends User{public Reader(String name){super(name);this.operates = new Operate[]{new exitOperate(),new findOperate(),new borrowOperate(),new returnOperate()};}@Overridepublic int menu() {Scanner scanner = new Scanner(System.in);System.out.println("***********读者***********");System.out.println("1.查找图书");System.out.println("2.借阅图书");System.out.println("3.归还图书");System.out.println("0.推出系统");System.out.println("**************************");System.out.print("请输入你的操作: ");int index = scanner.nextInt();return index;}
}

总结:大家最好自己实现一遍,实现的时候最好要明白自己在做什么,可以看看最后的结果来捋捋思路,可以看到我们使用到了接口,抽象类,包和继承的相关知识,只有在你使用他们的时候才会明白那里缺了。

结语:

其实写博客不仅仅是为了教大家,同时这也有利于我巩固自己的知识点,和一个学习的总结,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进,如果大家有所收获的话还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。

相关文章:

【项目】图书管理系统

目录 前言&#xff1a; 项目要求&#xff1a; 知识储备&#xff1a; 代码实现&#xff1a; Main&#xff1a; Books包&#xff1a; Book&#xff1a; BookList&#xff1a; Operate包&#xff1a; Operate: addOperate: deleteOperate: exitOperate: findOperate:…...

华为OD机试 - 疫情扩散时间计算 - 矩阵(Java 2024 C卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&am…...

[数据集][图像分类]棉花叶子病害分类数据集2293张4类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;2293 分类类别数&#xff1a;4 类别名称:["diseased_cotton_leaf"…...

《辐射4》是一款什么样的游戏 怎样在mac电脑上玩到《辐射4》辐射4攻略 辐射4开局加点 怎么在Mac电脑玩Steam游戏

辐射4&#xff08;Fallout 4&#xff09;是由Bethesda开发的一款动作角色扮演类游戏&#xff0c;为《辐射》系列游戏作品的第四代&#xff0c;于2015年11月10日发行。游戏叙述了主角一家在核爆当天&#xff08;2077年10月23日&#xff09;&#xff0c;被Vault-Tec&#xff08;避…...

视频推拉流EasyDSS平台直播通道重连无法转推的原因排查与解决

视频推拉流EasyDSS视频直播点播平台&#xff0c;集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 用户使用EasyDSS平台对直播通道进行转推&#xff0c;发现只要关闭…...

Javaweb之SpringBootWeb案例之自动配置案例的自定义starter测试的详细解析

3.2.4.3 自定义starter测试 阿里云OSS的starter我们刚才已经定义好了&#xff0c;接下来我们就来做一个测试。 今天的课程资料当中&#xff0c;提供了一个自定义starter的测试工程。我们直接打开文件夹&#xff0c;里面有一个测试工程。测试工程就是springboot-autoconfigurat…...

java包的相关概念

包&#xff1a;有效地管理类的一个机制。 包名的目的&#xff1a;通过隶属不同的包有效的区分不同源文件中名字相同的类 包语句 声明&#xff1a;通过关键字 package声明包语句。 位置&#xff1a;源文件中的第一条语句。 作用&#xff1a;为该源文件中声明的类指定包名。 …...

window搭建本地mongo数据库并导入数据

1 window下载mongo数据库 官网&#xff1a;www.mongodb.com 选择 Products > Community Edition 就能进入社区版 在这里下载 windows 版对应的安装包 注意&#xff1a;6.0.1 版本的 MongoDB 配置环境变量有问题&#xff0c;并且我不知道怎么解决&#xff0c;如果想要避免出…...

如何为Android车载应用开发通知?

如何为Android车载应用开发通知&#xff1f;在开发车载应用的通知时&#xff0c;开发者需要考虑到驾驶安全&#xff0c;确保通知不会分散驾驶员的注意力。这通常意味着通知应该是非侵入性的&#xff0c;或者在不影响驾驶的情况下提供信息。开发者可以使用Android的通知API来创建…...

centos上部署k8s

环境准备 四台Linux服务器 主机名 IP 角色 k8s-master-94 192.168.0.94 master k8s-node1-95 192.168.0.95 node1 k8s-node2-96 192.168.0.96 node2 habor 192.168.0.77 镜像仓库 三台机器均执行以下命令&#xff1a; 查看centos版本 [rootlocalhost Work]# cat /…...

网络安全: Kali Linux 进行 MSFvenom 程序利用

目录 一、实验 1.环境 2. Kali Linux 进行 MSFvenom 程序利用 3. 创建计划任务自动运行 MSFvenom 程序 二、问题 1.在线加密解密 2.MSF 运行失败 3.MobaXterm 连接Ubuntu 失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统版本IP备注Kali Linux20…...

浅显易懂C语言指针!!!(三)

文章目录 Pointers as function arguments - call by reference//函数传值vs传引用 Pointers as function arguments - call by reference//函数传值vs传引用 #include<stdio.h> void Increment(int a){//increment 增加 a a 1;//&#xff1b;函数中的是形式参数 形参…...

01 LM 算法及 Cpp 实现

文章目录 01 LM 算法及 Cpp 实现1.1 应用1.2 阻尼法推导1.3 Cpp 算法实现 01 LM 算法及 Cpp 实现 1.1 应用 LM 算法用于解决非线性最小二乘问题 min ⁡ x F ( x ) 1 2 ∥ f ( x ) ∥ 2 2 (1) \min _x F(x)\frac{1}{2}\|f(\boldsymbol{x})\|_2^2 \tag{1} xmin​F(x)21​∥f(x…...

【网络安全架构】互联网正对中国社会、经济、文化等各个领域产生巨大影响‘

摘 要&#xff1a; 中国互联网近年来飞速发展&#xff0c;普及率达到38.4%。已稳居世界第一网民大国的地位。互联网正对社会、经济、文化等各个领域产生巨大影响。2011年12月21日“泄密门”事件&#xff0c;再次敲响网络安全的警钟。网络攻击和入侵都是根据网络模型不同层次的特…...

【笔记】Android ServiceStateTracker 网络状态变化逻辑及SPN更新影响

业务简介 在网络状态变化的时候&#xff08;数据或WiFi&#xff09;&#xff0c;会更新SPN。 基于Android U的代码分析。 分类&#xff1a;SPN Data_Dic-的博客-CSDN博客 功能逻辑 状态说明 飞行模式下注册上WFC的话&#xff0c;注册状态MD上报 regState: NOT_REG_MT_NOT…...

2PC和3PC的区别是什么

2PC提交协议是什么 二阶段提交是指&#xff0c;在计算机网络一级数据库领域内&#xff0c;为了使基于分布式系统的架构下的所有节点在进行事务提交时保持一致性而设计的一种算法。在分布式系统中&#xff0c;每个节点虽然可以知晓自己操作的成功和失败&#xff0c;但是无法知道…...

redis未设置密码被植入挖矿脚本

最近一台测试linux响应速度贼慢&#xff0c;检查发现cpu消耗高达100%&#xff01;查看进程杀死后过段时间又重启了&#xff0c;一时间也摸不到头绪。无意间发现启动redis的时候cpu瞬间拉到了100%&#xff0c;主要就是zzh和newinit.sh两个脚本。百度了一下说是被植入了挖矿脚本&…...

轮询--一起学习吧之架构

一、定义 轮询&#xff08;Polling&#xff09;是一种CPU决策如何提供周边设备服务的方式&#xff0c;又称“程控输出入”&#xff08;Programmed I/O&#xff09;。这种方式是由CPU定时发出询问&#xff0c;依序询问每一个周边设备是否需要其服务&#xff0c;有即给予服务&am…...

【开发工具】Git模拟多人开发场景理解分支管理和远程仓库操作

我们来模拟一个多人多分支的开发场景。假设你有一个新的空白远程仓库,假设地址是 https://github.com/user/repo.git。 克隆远程仓库到本地 $ git clone https://github.com/user/repo.git这会在本地创建一个 repo 目录,并自动设置远程主机为 origin。 创建本地开发分支并推送…...

从零学习Linux操作系统 第三十一部分 ansible常用模块介绍

一、ansible运行模块的两种方式 Ad-Hoc方式 ##利用ansible命令直接完成管理&#xff0c;主要用于临时命令使用场景 playbook方式 ##ansible脚本&#xff0c;主要用于大型项目场景&#xff0c;需要前期的规划&#xff0c;相当于shell当中的脚本 二、如何查看模块帮助 ansible…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...