五分钟”手撕“图书管理系统
前言:
图书馆管理系统需要结合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…...
别再死记硬背SMO公式了!用Python手写一个SVM分类器,带你一步步拆解SMO核心逻辑
用Python手写SVM分类器:代码驱动理解SMO算法核心在机器学习领域,支持向量机(SVM)以其优秀的分类性能和坚实的数学基础著称。然而,许多学习者在理解其核心算法——序列最小优化(SMO)时,往往被复杂的数学推导所困扰。本文将采用一种…...
终极鼠标连点器使用指南:3分钟掌握高效自动化技巧
终极鼠标连点器使用指南:3分钟掌握高效自动化技巧 【免费下载链接】MouseClick 🖱️ MouseClick 🖱️ 是一款功能强大的鼠标连点器和管理工具,采用 QT Widget 开发 ,具备跨平台兼容性 。软件界面美观 ,操作…...
从BUG()到panic:深入Linux 5.4内核,看异常处理如何层层递进
从BUG()到panic:Linux内核异常处理的防御体系全解析当你在深夜调试一个内核模块时,突然屏幕刷出一串红色警告——这可能是每个Linux内核开发者都经历过的噩梦时刻。但你是否想过,从第一行警告出现到系统完全崩溃,内核究竟经历了怎…...
Windows10下V-REP教育版安装保姆级教程(附百度网盘资源与避坑点)
Windows10系统V-REP教育版完整安装指南:从下载到实战避坑在机器人仿真和自动化控制领域,V-REP(现更名为CoppeliaSim)作为一款功能强大的跨平台机器人仿真软件,已经成为众多工科学生和研究人员的首选工具。特别是其教育…...
rk35xx 通过recovery升级问题
Firefly 的 recovery 库是一个核心组件,它构建了一个独立的微型 Linux 系统,专门用于在设备主系统之外执行高可靠性的固件升级。简单来说,它的工作流程是:主系统通过命令触发,将升级指令写入特定分区并重启;…...
AI学习 - 大模型基础入门
AI学习 - 大模型基础入门 从零开始:Ollama 安装 → 本地模型运行 → Python 代码接入 → 理解核心概念 摘要 本文记录了在 Windows 上使用 Ollama 部署本地大模型、并通过 Python 代码接入调用的完整过程。内容涵盖:Ollama 安装与模型拉取、大模型基础概…...
16个分片+2副本:pg_shard的master_create_worker_shards最佳实践
16个分片2副本:pg_shard的master_create_worker_shards最佳实践 【免费下载链接】pg_shard ATTENTION: pg_shard is superseded by Citus, its more powerful replacement 项目地址: https://gitcode.com/gh_mirrors/pg/pg_shard pg_shard作为PostgreSQL的分…...
独立开发者如何利用Taotoken Token Plan,以更低成本启动AI项目
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 独立开发者如何利用Taotoken Token Plan,以更低成本启动AI项目 对于独立开发者或小型团队而言,启动一个集成…...
从模糊到电影级景深:Midjourney + Topaz Gigapixel联调方案(含LUT预设包+PSD分层模板)
更多请点击: https://codechina.net 第一章:从模糊到电影级景深:Midjourney Topaz Gigapixel联调方案(含LUT预设包PSD分层模板) 当Midjourney生成的图像存在主体边缘柔化、背景层次缺失或分辨率不足等问题时…...
3大技术突破:重新定义Switch游戏安装性能极限
3大技术突破:重新定义Switch游戏安装性能极限 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer Awoo Installer是一款专为破解版Nintendo…...
