五分钟”手撕“图书管理系统
前言:
图书馆管理系统需要结合JavaSE的绝大部分知识,是一个很好的训练项目。
为了让大家更加方便的查阅与学习,我把代码放开头,供大家查询。
还有对代码的分析,我将以类为单位分开讲解。
目录
全部代码
Main类
User类
BookList类
Book类
NormalUser类
全部代码
/*一共有三个包*///User包
//User.java
package user;
import Book.BookList;
import Operation.IOparetion;public abstract class User {protected String name;protected IOparetion[] iOparetions;public User(String name) {this.name = name;}public abstract int menu();public void doIOparetion(int chioce, BookList bookList){this.iOparetions[chioce].work(bookList);}
}//User包
//NormalUser.java
package user;
import Operation.*;
import java.util.Scanner;public class NormalUser extends User{public NormalUser(String name) {super(name);this.iOparetions= new IOparetion[] {new ExitOparetion(),new FindOparetion(),new BorrowedOparetion(),new ReturnOparetion()};}@Overridepublic 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包
//Administrators.java
package user;
import Operation.*;
import java.util.Scanner;public class Administrators extends User {public Administrators(String name) {super(name);this.iOparetions = new IOparetion[]{new ExitOparetion(),new FindOparetion(),new AddOparetion(),new DelOparetion(),new ShowOparetion()};}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;}
}//Book包
//Book.java
package Book;public class Book {private String name;private String author;private int price;private String type;private boolean isLend;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 isLend() {return isLend;}public void setLend(boolean lend) {isLend = lend;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +", type='" + type + '\'' +(isLend==true?"已借出":"未借出")+'}';}
}//Book包
//BookList.java
package Book;public class BookList {private Book[] book=new Book[10];private int usedSize;public Book getBook(int pos) {return book[pos];}public void setBook(int pos,Book book) {this.book[pos] = book;}public int getUsedSize() {return usedSize;}public void setUsedSize(int usedSize) {this.usedSize = usedSize;}public BookList() {book[0]=new Book("西游记","吴承恩",19,"小说");book[1]=new Book("三国演义","罗贯中",36,"小说");book[2]=new Book("红楼梦","曹雪芹",13,"小说");this.usedSize=3;}public boolean isFull(){if(usedSize==book.length){return true;}return false;}
}//Oparetion包
//Ioparetion.java
package Operation;import Book.BookList;public interface IOparetion {void work(BookList bookList);
}//Oparetion包
//AddOparetion.java
package Operation;import Book.Book;
import Book.BookList;
import java.util.Scanner;public class AddOparetion implements IOparetion {@Overridepublic void work(BookList bookList) {Scanner scanner=new Scanner(System.in);System.out.println("请输入你要添加的书籍名字");String name=scanner.nextLine();System.out.println("请输入作者的名字");String author=scanner.nextLine();System.out.println("请输入书的种类");String type=scanner.nextLine();System.out.println("请输入书的价格");int price=scanner.nextInt();Book book=new Book(name,author,price,type);if(bookList.isFull()){System.out.println("书架满了,借阅失败");return;}bookList.setBook(bookList.getUsedSize(), book);bookList.setUsedSize(bookList.getUsedSize()+1);System.out.println("添加成功");}
}//Oparetion包
//BorrowedOparetion.java
package Operation;import Book.BookList;
import java.util.Scanner;public class BorrowedOparetion implements IOparetion{@Overridepublic void work(BookList bookList) {System.out.println("请输入你要找的书名");Scanner scanner=new Scanner(System.in);String name=scanner.nextLine();for(int i=0;i<bookList.getUsedSize();i++){if(name.equals(bookList.getBook(i).getName())){bookList.getBook(i).setLend(true);System.out.println("借阅成功");return;}}System.out.println("借阅失败");}}//Oparetion包
//DelOparetion.java
package Operation;import Book.BookList;
import java.util.Scanner;public class DelOparetion implements IOparetion{@Overridepublic void work(BookList bookList) {System.out.println("请输入你要删除的书籍名字");Scanner scanner=new Scanner(System.in);String s=scanner.nextLine();int pos=-1;int i=0;for (;i<bookList.getUsedSize();i++){if(s.equals(bookList.getBook(i))){pos=i;}if(i>=bookList.getUsedSize()){System.out.println("没有你要找的书");return;}}for(int j=i;i<bookList.getUsedSize()-1;i++){bookList.setBook(j,bookList.getBook(j+1));}bookList.setBook(bookList.getUsedSize(), null);bookList.setUsedSize(bookList.getUsedSize()-1);System.out.println("删除成功");}
}//Oparetion包
//ExitOparetion.java
package Operation;
import Book.BookList;public class ExitOparetion implements IOparetion {@Overridepublic void work(BookList bookList) {System.out.println("退出系统中....");for(int i=0;i<bookList.getUsedSize()-1;i++){bookList.setBook(i,null);}System.exit(0);}
}//Oparetion包
//FindOparetion.java
package Operation;import Book.BookList;
import java.util.Scanner;public class FindOparetion implements IOparetion{@Overridepublic void work(BookList bookList) {System.out.println("请输入你要找的书名");Scanner scanner=new Scanner(System.in);String name=scanner.nextLine();for(int i=0;i<bookList.getUsedSize();i++){if(name.equals(bookList.getBook(i).getName())){System.out.println("找到了,下标为:"+i);System.out.println(bookList.getBook(i));return;}}System.out.println("没找到");}
}//Oparetion包
//ReturnOparetion.java
package Operation;import Book.BookList;
import java.util.Scanner;public class ReturnOparetion implements IOparetion{@Overridepublic void work(BookList bookList) {Scanner scanner=new Scanner(System.in);System.out.println("请输入你要归还的书名");String s=scanner.nextLine();for (int i = 0; i < bookList.getUsedSize()-1; i++) {if(s.equals(bookList.getBook(i).getName())){bookList.getBook(i).setLend(false);System.out.println("归还成功");return;}}System.out.println("归还失败,没有你要归还的书");}
}//Oparetion包
//ShowOparetion.java
package Operation;
import Book.BookList;public class ShowOparetion implements IOparetion{@Overridepublic void work(BookList bookList) {for(int i=0;i<bookList.getUsedSize();i++){System.out.println(bookList.getBook(i));}}}
首先,我们需要打个框架出来,由于java是一门面向对象的编程,所以我们应该要多考虑对象,而不是过程。
我将它分为三个包:User、Book、operation包,其实对象有:书架、书、用户、管理员。
总体请看下图:

这里我主要讲解大致结构和细微的细节 ,因为方法的思路在数据结构讲解更加清晰
Main类
public class Main {public static User login(){Scanner scanner=new Scanner(System.in);System.out.println("请输入你的名字");String name=scanner.nextLine();System.out.println("请输入你的身份:1.普通用户 2.管理员用户");int choice =scanner.nextInt();if(choice==1){NormalUser normalUser=new NormalUser(name);return normalUser;}else{Administrators administrators=new Administrators(name);return administrators;}}public static void main(String[] args) {BookList bookList=new BookList();User user=login();while (true){int ret=user.menu();user.doIOparetion(ret,bookList);}}
}
上述代码中:
Scanner来new一个对象来输入,int一个choice来接收选1还是2,选择是管理人还是普通用户。
由于要返回一个对象,所以login的返回值是user类型的,user与管理员和普通用户是父子关系,在main中用user类型接收,属于向上转型(好处就是发生多态)。
User类
package user;
import Book.BookList;
import Operation.IOparetion;public abstract class User {protected String name;protected IOparetion[] iOparetions;public User(String name) {this.name = name;}public abstract int menu();public void doIOparetion(int chioce, BookList bookList){this.iOparetions[chioce].work(bookList);}
}
上述代码中:
User作为父类,被管理员和普通用户继承,被abstract修饰主要是为了menu这个方法被继承,实现多态。
IOparetion是一个接口,是为了被那些add和del等等方法实现的,还是实现多态,
它现在作为一个数组来接收,是为了存放这些方法,这样就不用一个个在用户或者管理员里面书写了,可以直接定义为一个类(这也是为什么方法可以另外书写的原因),这体现了面向对象的特点,大大缩短了工程量和分模块的简洁性(即使下次有人需要用,不需要再写,直接调用就好了)。
BookList类
package Book;public class BookList {private Book[] book=new Book[10];private int usedSize;public Book getBook(int pos) {return book[pos];}public void setBook(int pos,Book book) {this.book[pos] = book;}public int getUsedSize() {return usedSize;}public void setUsedSize(int usedSize) {this.usedSize = usedSize;}public BookList() {book[0]=new Book("西游记","吴承恩",19,"小说");book[1]=new Book("三国演义","罗贯中",36,"小说");book[2]=new Book("红楼梦","曹雪芹",13,"小说");this.usedSize=3;}public boolean isFull(){if(usedSize==book.length){return true;}return false;}
}
对于上述代码:
由于java是面向对象编程,所以对于一些信息不需要用户来知道内部是怎么实现的,所以用private修饰,这样的话需要set和get方法来获取,这样之后的代码都需要调用set和get来获取或者是赋值。
BookList是书架,所以里面是摆书的,所以用Book类型作为数组,来收取book。可以放很多本。
usedsize是有效书籍数,就是记录里面有多少本。
Book类
package Book;public class Book {private String name;private String author;private int price;private String type;private boolean isLend;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 isLend() {return isLend;}public void setLend(boolean lend) {isLend = lend;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +", type='" + type + '\'' +(isLend==true?"已借出":"未借出")+'}';}
}
对于上述代码:
Book是类,它代表的是一本书,所以你需要定义名字作者价格什么什么的。
也是利用封装,只把必要的信息给用户,所以用privat密封起来,更加安全一点,所以需要set和get方法。
这里的toString方法里面有个三目操作符,如果isLend被借出的话,就是true,就会打印已借出,否则为借出。
NormalUser类
package user;
import Operation.*;
import java.util.Scanner;public class NormalUser extends User{public NormalUser(String name) {super(name);this.iOparetions= new IOparetion[] {new ExitOparetion(),new FindOparetion(),new BorrowedOparetion(),new ReturnOparetion()};}@Overridepublic 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;}
}
对于上述代码:
如果继承了父类,使用构造方法时候需要先把父类的构造方法实现。
因为IOparetion是user里面的,user被普通用户继承,所以可以直接访问,把他变成一个数组,这样就可以存方法了,不用在这普通用户这个类里一个一个方法写,直接脱离出来,非常充分体现了面向对象的特点!
相关文章:
五分钟”手撕“图书管理系统
前言: 图书馆管理系统需要结合JavaSE的绝大部分知识,是一个很好的训练项目。 为了让大家更加方便的查阅与学习,我把代码放开头,供大家查询。 还有对代码的分析,我将以类为单位分开讲解。 目录 全部代码 Main类 Us…...
8个实用网站和软件,收藏起来一定不后悔~
整理了8个日常生活中经常能用得到的网站和软件,收藏起来一定不会后悔~ 1.ZLibrary zh.zlibrary-be.se/这个网站收录了超千万的书籍和文章资源,国内外的各种电子书资源都可以在这里搜索,98%以上都可以在网站内找到,并且支持免费下…...
电商内卷时代,视频号小店凭借一己之力“脱颖而出”
大家好,我是电商笨笨熊 今年618各大电商平台花样百出; 某宝更是直接取消了“预售”,从5月就开始进入618预热期; 不少玩家既开心又难过,市场如此内卷,618确实是个爆发期,但更多的需要不断压低…...
【论文笔记】| 定制化生成PuLID
PuLID: Pure and Lightning ID Customization via Contrastive Alignment ByteDance, arXiv:2404.16022v1 Theme: Customized generation 原文链接:https://arxiv.org/pdf/2404.16022 Main Work 提出了 Pure 和 Lightning ID 定制 (PuLID),这是一种用于…...
P1638 逛画展
题目描述 博览馆正在展出由世上最佳的 𝑚 位画家所画的图画。 游客在购买门票时必须说明两个数字,𝑎 和 𝑏,代表他要看展览中的第 𝑎 幅至第 𝑏 幅画(包含 𝑎,…...
Linux(centos)常用命令
Linux(Centos)常用命令使用说明文档 切换到/home目录下 使用cd命令切换目录,例如: cd /home列出/home目录下的所有文件 使用ls命令列出目录下的文件和子目录,例如: ls /home新建目录dir1 使用mkdir命…...
从入门到精通:掌握Scrapy框架的关键技巧
在当今信息爆炸的时代,获取并利用网络数据成为了许多行业的核心竞争力之一。而作为一名数据分析师、网络研究者或者是信息工作者,要想获取网络上的大量数据,离不开网络爬虫工具的帮助。而Scrapy框架作为Python语言中最为强大的网络爬虫框架之…...
Vue3按顺序调用新增和查询接口
Vue3按顺序调用新增和查询接口 一、前言1、代码 一、前言 如果你想将两个调用接口的操作封装在不同的方法中,你可以考虑将这两个方法分别定义为异步函数,并在需要时依次调用它们。以下是一个示例代码: 1、代码 <template><div>…...
sizeof的了解
32位编译器 qDebug() << "int:" << sizeof(int);qDebug() << "char:" << sizeof(char);qDebug() << "char*:" << sizeof(char*); 字节数: int: 4 char: 1 char*: 4 64位编译器 字节数&#…...
PostgreSQL 教程
## PostgreSQL 教程 ### 1. PostgreSQL 概述 PostgreSQL 是一个开源的对象关系型数据库管理系统(ORDBMS),以其高扩展性和合规性闻名,支持 SQL 和 JSON 查询。 ### 2. 安装与配置 - **下载与安装**:从 PostgreSQL 官方…...
《基于Jmeter的性能测试框架搭建》改进一
《基于Jmeter的性能测试框架搭建》文末笔者提到了不少待改进之处,如下所示。 Grafana性能图表实时展现,测试过程中需实时截图形成测试报告,不够人性化。解决方案:自动生成测试报告并邮件通知。 Grafana性能图表需测试人员实时监控…...
计算机二进制表示和存储各种数据
目录 计算机二进制是什么 计算机中二进制数作用 不同数据的表示和存储 数字 文字 图片 音频 视频 计算机的中数据的显示和存储 计算机二进制是什么 计算机二进制数:计算机里存储的一切都是以二进制的0和1来表示。二进制是计算机使用的数字编码系统&#x…...
玩机社区 - 2024年最美社区源码开源
玩机社区 - 2024年最美社区源码开源 教程源码文档都内置到压缩包了 https://pan.baidu.com/s/1xwcscTne-JMbmKEntiuAuA?pwd78oi...
Linux系统——面试题分享
目录 1.现在给你三百台服务器,你怎么对他们进行管理? 2.简述 raid0 raid1 raid5 三种工作模式的工作原理及特点 2.1RAID 0 ——可以是一块盘和 N 个盘组合 2.2RAID 1 ——只能2块盘,盘的大小可以不一样,以小的为准 2.3RAID 5 …...
谈恋爱没经验?那就来刷谈恋爱经验宝宝吧
❤️作者主页:小虚竹 ❤️作者简介:大家好,我是小虚竹。2022年度博客之星评选TOP 10🏆,Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作…...
element-ui输入框和多行文字输入框字体不一样解决
element-ui的type"textarea"的字体样式与其他样式不同 <el-input type"textarea"></el-input> <el-input ></el-input>设置: .el-textarea__inner::placeholder {font-family: "Helvetica Neue", Helvetic…...
(Java企业 / 公司项目)配置Linux网络-导入虚拟机
公司给了我一个IP地址 ,提供了一个虚拟机或者自己搭建虚拟机,还有提供登录的账号密码 可以查看我之前的文章 VMware Workstation Pro 17虚拟机超级详细搭建(含redis,nacos,docker, rabbitmq,sentinel&…...
java的unsafe
在Java中,sun.misc.Unsafe 是一个强大且危险的类,它提供了一些直接操作内存、对象和线程的底层功能。这个类通常不鼓励普通开发者使用,因为它绕过了Java语言的一些安全性和内存管理机制,可能会导致难以追踪的错误和安全漏洞。 Un…...
起底震网病毒的来龙去脉
2010年,震网病毒被发现,引起世界哗然,在后续的10年间,陆陆续续有更多关于该病毒的背景和细节曝光。今年,《以色列时报》和《荷兰日报》又披露了关于此事件的更多信息,基于这些信息,我们重新梳理…...
[杂项]优化AMD显卡对DX9游戏(天谕)的支持
目录 关键词平台说明背景RDNA 1、2、3 架构的显卡支持游戏一、 优化方法1.1 下载 二、 举个栗子(以《天谕》为例)2.1 下载微星 afterburner 软件 查看游戏内信息(可跳过)2.2 查看D3D9 帧数2.3 关闭游戏,替换 dll 文件2…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
