邦布带你从零开始实现图书管理系统(java版)

今天我们来从零开始实现图书管理系统。

图书管理系统

来看我们的具体的实现,上述视频。

我们首先来实现框架,我们要实现图书管理系统,首先要搭框架。

我们首先定义一个书包,在书包中定义一个书类和一个书架类,再定义一个用户包,其中包含用户类,管理者类,普通用户类,在定义一个工具包来实现具体操作,定义一个主函数。

我们先来实现Book类

public class Book {private String name;private String author;private int price;private String type;private boolean isBorrowed;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 isBorrowed() {return isBorrowed;}public void setBorrowed(boolean borrowed) {isBorrowed = borrowed;}public String toString(){return "Book{" + "姓名:" + name + '/' + "作者:" + author + '/' + "价格:" +price + '/' + "类型" + type + '/'+ ((isBorrowed==true)?"已借阅":"未借出");}
}

我们对书进行描述的类,包含书名,作者名,价格,类型,和书是否被借出的状态,我们提供对name,author,price,type初始化的构造方法,为什么不对isborrowed进行初始化呢,因为boolean开始就是false,我们在进行ALT + Insert对所有字段提供getter and setter因为我们的权限是private。

最后对toString函数进行重写,来保证我们使用System.out.println()的时候可以输出我们book,对象的全部属性,那么这个((isborrowed)?已借阅":"未借出")是什么呢,我们isBorrowed默认是false所以默认是未借出,当我们后期修改isBorrow的时候就能达到true是已借阅的情况了。用的条件表达式,如果isBorrowed==true那么就是已借阅否则就是未借出。

我们下面实现书架类

public class BookList {Book[] Books = new Book[10];private int usedSize;public BookList(){this.Books[0] = new Book("三国演义","罗贯中",20,"小说");this.Books[1] = new Book("西游记","吴承恩",38,"小说");this.Books[2] = new Book("红楼梦","曹雪芹",30,"小说");this.usedSize=3;}public int getUsedSize() {return usedSize;}public void setUsedSize(int usedSize) {this.usedSize = usedSize;}public Book[] getBooks() {return Books;}public void setBooks(Book[] books) {Books = books;}
}

我们首先创建一个数组,我们用书类来定义一个书类数组,类似实现书架的功能,再定义usedSize来表示书架上到底有多少书,再提供构造方法的时候我们除了初始化我们的uesdSize,还要再Books数组中放入3本书来保证我们创建书架的时候就已经有书了,再提供Books数组和usedSize的Getter和Setter,Books数组的Gette和Setter有问题,我们后面再说

我们再来定义main类来跑程序

我们看我们运行的时候,

会有一个登录界面,我们在Main类中实现它

public class Main {public static void login(){}public static void main(String[] args) {BookList bookList = new BookList();login();}
}

我们在Main类中创建了一个书架对象,生成了刚才创建的三本书,我们通过login函数来实现登录界面

    public static void login(){Scanner scanner = new Scanner(System.in);System.out.println("请输入你的姓名");String name = scanner.nextLine();System.out.println("请输入你的身份 1, 管理员 2, 用户");String choice = scanner.nextLine();}

我们实现了输入并用name记住了姓名,用choice记住了选择

我们还可以去设计密码来限制是否为管理员登入

    public static void 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){while (true){System.out.println("请输入密码");int count = scanner.nextInt();if(count==123456){System.out.println("密码正确");return;//进入管理员菜单}else{System.out.println("是否重新输入密码 1,是 2,否");int count2 = scanner.nextInt();if(count2==1){continue;}else {break;}}}}return;}

我们用循环和if语句来实现个简单的密码限制,这里就不过多描述了,我们既然有了选择,就要实现两个类来创建不同的对象,

这样就实现了两个不同的用户菜单,这里菜单名字忘改了,但是他们对书架操作的权限是不同的

我们现在来实现这个用户类

public abstract class User {protected String name;public User(String name){this.name = name;}public abstract int menu();
}

我们创建了三个类,User是我们的父类,而其他两个是我们的子类,为什么要这样设计呢,因为我们在Main类运行代码的时候,调用一个父类User来利用多态,对字类重写的方法进行调用会更好,就刚才我们进行的选择,我们会创建不同的对象,密码正确我们会创建AdminUser对象,NormalUser对象,而使用继承我们可以直接把他向上转型为User类,用Uesr类来调用,话不多说我们直接上代码

先导入我们需要的包,

在子类AdminUser中操作

public class AdminUser extends User{public AdminUser(String name){super(name);}@Overridepublic int menu() {System.out.println("欢迎" + name + "管理员" + "来到电子图书馆");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("****************");return 0;}
}

在之前的Main中如果是管理员的话返回一个新的管理员对象,但是问题来了我们返回值不是void吗、

我们将返回值给上User这下不彻底穿起来了,我们就可以用user来访问管理员对象了,使用了我们的多态

public class NormalUser extends User {public NormalUser(String name) {super(name);}public int menu() {System.out.println("欢迎" + name + "用户" + "来到电子图书馆");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("****************");return 0;}
}

在把用户的写了,我们再主类中去调用

再完整的展示下login函数

    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){while (true){System.out.println("请输入密码");int count = scanner.nextInt();if(count==123456){System.out.println("密码正确");return new AdminUser(name);//进入管理员菜单}else{System.out.println("是否重新输入密码 1,是 2,否");int count2 = scanner.nextInt();if(count2==1){continue;}else {break;}}}}return new NormalUser(name);}

可以根据不同的选择返回管理员对象,或者用户对象

    public static void main(String[] args) {BookList bookList = new BookList();User user = login();while(true){user.menu();}}

我们就可以用父类user 来接收我们传过来的对象,发生了向上转型,我们可以通过user来调用我们在子类中重写的menu方法来显示不同的菜单

我们这时候运行就会显示两种不同的菜单,可以会有同学不明白为啥meun函数返回值是int,因为就要进行我们接下来的操作对每个选项的实现,所以在菜单界面我们就要接受我们选择的选项

我们在Main类中接收我们的选择

接下来就要实现具体操作。

我们在工具类进行操作,想想我们要怎么通过菜单的调用就能调用出具体的方法呢,

我们定义了这些类,每个类包含了对应的方法,还是那个问题,怎么通过菜单来访问对应的方法呢,最直观的就是类中有这些方法,这时我们就要用到接口了,让每个操作都用到了这个接口,而我们的管理员类和普通用户类中让他有接口的数组,这个用户中有哪个操作接口数组中就包含哪个。话不多说,我们继续进行操作

我们创建一个接口

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

让这个接口包含对书架操作的功能

让其他所有操作都包含这个接口

public class AddOPeration implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("添加图书");}
}

后面的就不一一列举了

我们在父类User中创建一个接口数组

public class NormalUser extends User {public NormalUser(String name) {super(name);this.IOPerations = new IOPeration[]{new ExitOPeration(),new BorrowOPeration(),new ReturnOPeration(),new FindOPeration()};}public int menu() {System.out.println("欢迎" + name + "用户" + "来到电子图书馆");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.println("请输入您的操作");int choice = scanner.nextInt();return choice;}
}

这样普通用户类就包含了他所需要的功能,我们的普通用户也彻底定义完了

public class AdminUser extends User{public AdminUser(String name){super(name);this.IOPerations = new IOPeration[]{new ExitOPeration(),new AddOPeration(),new DelOPeration(),new FindOPeration(),new ShowOPeration()};}@Overridepublic int menu() {System.out.println("欢迎" + name + "管理员" + "来到电子图书馆");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.println("请输入您的操作");int choice = scanner.nextInt();return choice;}
}

管理员用户我们也彻底定义完了,接下来就是实现用户对每个操作的调用我们首先要解决遗留问题

就是刚才我们对书架中的Getter和Setter不合理

我们想得到的是具体的书,放置书到书架具体的位置

    public Book getBooks(int pos) {return Books[pos];}public void setBooks(int pos, Book book) {Books[pos] = book;}

父类用户中

    public void DoOPeration(int choice, BookList bookList){IOPerations[choice].work(bookList);}

主类中

    public static void main(String[] args) {BookList bookList = new BookList();User user = login();while(true){int choice = user.menu();user.DoOPeration(choice,bookList);}}

这样我们就能在具体菜单中根据选择中进行具体的操作了

其他的我们就不一一展示了,接下来就是我们对操作的具体实现了,马上结束了不用心急。

1,结束类方法

public class ExitOPeration implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("退出系统");System.exit(0);}
}

直接System.exit(0)意思为程序正常退出

2,查找类方法

public class FindOPeration implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("查找图书");Scanner scanner = new Scanner(System.in);System.out.println("请输入你要查找的书名");String name = scanner.nextLine();int count = bookList.getUsedSize();for (int i = 0; i < count; i++) {Book book = bookList.getBooks(i);if (book.getName().equals(name)){System.out.println(book);return;}}System.out.println("没有这本书");}
}

我们使用循环进行比较即可,如果name和我们book中的name相同就可以输出了

3,添加类方法

    public Book[] getbooksize(){return Books;}

在书架booklist中定义一个得到数组的函数,方便我们获得长度,因为我们在进行添加书的时候要判断书架是否满了。再创建一个book对象把新输入的属性,生成一本新的数,在把书放到书架上,之后记录书多了一本。

public class AddOPeration implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("添加图书");Scanner scanner = new Scanner(System.in);int size = bookList.getUsedSize();int size2 = bookList.getbooksize().length;if(size2==size){System.out.println("书架满了,无法添加");}else {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);bookList.setBooks(size,book);bookList.setUsedSize(size+1);}}
}

4,借阅类方法

在借阅方法中还是一样我们把查找的方法拿来,其实都是利用查找的方法,再扩展,

如果找到了,就把book的属性改为true就是已借出。

public class BorrowOPeration implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("借阅图书");Scanner scanner = new Scanner(System.in);System.out.println("请输入你要借阅的书名");String name = scanner.nextLine();int count = bookList.getUsedSize();for (int i = 0; i < count; i++) {Book book = bookList.getBooks(i);if (book.getName().equals(name)){if(book.isBorrowed()==false){book.setBorrowed(true);System.out.println("借阅成功");return;}else {System.out.println("书已经被借走了");return;}}else{System.out.println("没有这本书");}}}
}

5,归还类方法

和借阅一模一样,就改下书的isBorrowed状态就行

public class ReturnOPeration implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("归还图书");Scanner scanner = new Scanner(System.in);System.out.println("请输入你要归还的书名");String name = scanner.nextLine();int count = bookList.getUsedSize();for (int i = 0; i < count; i++) {Book book = bookList.getBooks(i);if (book.getName().equals(name)){if(book.isBorrowed()==true){book.setBorrowed(false);System.out.println("归还成功");return;}else {System.out.println("书已经归还了");return;}}else{System.out.println("没有这本书");}}}
}

6,展示类方法

更简单了,我们直接循环遍历我们的书架就行了

public class ShowOPeration implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("展示图书");int count = bookList.getUsedSize();for (int i = 0; i < count; i++) {Book book = bookList.getBooks(i);System.out.println(book);}}
}

7,删除类方法

public class DelOPeration implements IOPeration{@Overridepublic void work(BookList bookList) {System.out.println("删除图书");Scanner scanner = new Scanner(System.in);System.out.println("请输入你要删除的书名");String name = scanner.nextLine();int pos = -1;int i = 0;int count = bookList.getUsedSize();for (i=0; i < count; i++) {Book book = bookList.getBooks(i);if (book.getName().equals(name)){break;}}if (count==i){System.out.println("你要删除的书不存在");return;}for (int j = pos; j < count-1; j++) {Book book = bookList.getBooks(j+1);bookList.setBooks(j,book);System.out.println("删除成功");bookList.setUsedSize(count-1);bookList.setBooks(count-1,null);}}
}

我们还是利用查找,找到了之后,利用顺序表尾删的方法就可以了,一个一个覆盖,减少书架usedsize的声明即可。

下面放上源码来方便大家学习

博客结合的通讯录 · 75122bd · 王涛c语言/test_c_study - Gitee.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3270287.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

51单片机15(直流电机实验)

一、序言&#xff1a;我们知道在单片机当中&#xff0c;直流电机的控制也是非常多的&#xff0c;所以有必要了解一些这个电机相关的一些知识&#xff0c;以及如何使用单片机来控制这个电机&#xff0c;那么在没有学习PWM之前&#xff0c;我们先简单的使用GPIO这个管脚来控制电机…

女人内裤怎么洗才是最干净?内衣裤洗衣机怎么样?哪个牌子更好?

最近刚好用到一款比较好用的洗内衣裤洗衣机&#xff01;如果你也和我一样有洗内衣裤烦恼的&#xff0c;或者可以看看&#xff01; 内衣裤作为贴身穿的衣服&#xff0c;我是不会把它和外衣一起清洗的&#xff0c;而家里面的大洗衣机已经担起了清洗外衣的工作&#xff01; 朋友们…

jdk的major version和minor version是啥意思?

写在前面 1&#xff1a;正文 major version是大版本号&#xff0c;minor version是小版本号&#xff0c;但目前minor version都是0&#xff08;也可能是我没有发现&#x1f605;&#xff09;&#xff0c;如jdk8就是52&#xff0c;如下表&#xff1a; 可以看到jdk版本号和ma…

优思学院:六西格玛黑带的价值仍在吗?

六西格玛自20世纪80年代由摩托罗拉提出以来&#xff0c;已经深刻地影响了全球的质量管理实践。六西格玛方法论中的一个关键角色就是“黑带”&#xff0c;这些人经过培训&#xff0c;能够领导问题解决项目。随着进入数字化时代&#xff0c;自动化和数据分析在商业运营中变得越来…

【区块链】JavaScript连接web3钱包,实现测试网络中的 Sepolia ETH余额查询、转账功能

审核看清楚了 &#xff01; 这是以太坊测试网络&#xff01;用于学习的测试网络&#xff01;&#xff01;&#xff01; 有关web3 和区块链的内容为什么要给我审核不通过&#xff1f; 别人凭什么可以发&#xff01; 目标成果&#xff1a; 实现功能分析&#xff1a; 显示账户信…

第N8周:图解NLP中的注意力机制

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、前期知识储备 注意力机制是一种模拟人类大脑注意力分配方式的计算模型&#xff0c;它能够在处理大量信息时&#xff0c;聚焦于重要的部分&#xff0c;而忽…

打卡第二十五天:递增子序列、全排列、全排列II、重新安排行程、N皇后、解数独

1、递增子序列 题目 文章 视频 这个递增子序列比较像是取有序的子集。而且本题也要求不能有相同的递增子序列。在子集一题中通过排序&#xff0c;再加一个标记数组来达到去重的目的。而本题求自增子序列&#xff0c;是不能对原数组进行排序的&#xff0c;排完序的数组都是自…

数据结构:(1)线性表

一、基本概念 概念&#xff1a;零个或多个数据元素的有限序列 元素之间是有顺序了。如果存在多个元素&#xff0c;第一个元素无前驱&#xff0c;最后一个没有后继&#xff0c;其他的元素只有一个前驱和一个后继。 当线性表元素的个数n&#xff08;n>0&am…

NzN的C语言全解析--C语言常见概念

目录 1. C语言是什么&#xff1f; 2. C语言的历史 3. 编译器的选择--VS2022 (1) 编译和链接 (2) VS2022 的优缺点 4. VS项目和源文件、头文件介绍 5. 第一个C语言程序 6. main函数 7. printf和库函数 8. 关键字 9. 字符和ASCII编码 10. 字符串和\0 11. 转义字符 …

文件系统基础(一)

目录 一 . 文件的基本概念文件的结构文件的属性文件的分类 二. 文件控制块和索引节点文件控制块&#xff08;FCB&#xff09;索引节点磁盘索引节点内存索引节点 三. 文件的操作文件的基本操作文件的打开与关闭文件打开文件关闭文件名与文件描述符的应用 四. 文件的保护访问类型…

用PyTorch从零开始编写DeepSeek-V2

DeepSeek-V2是一个强大的开源混合专家&#xff08;MoE&#xff09;语言模型&#xff0c;通过创新的Transformer架构实现了经济高效的训练和推理。该模型总共拥有2360亿参数&#xff0c;其中每个令牌激活21亿参数&#xff0c;支持最大128K令牌的上下文长度。 在开源模型中&…

Godot入门 02玩家1.0版

添加Node2D节点&#xff0c;重命名Game 创建玩家场景&#xff0c;添加CharacterBody2D节点 添加AnimatedSprite2D节点 从精灵表中添加帧 选择文件 设置成8*8 图片边缘模糊改为清晰 设置加载后自动播放&#xff0c;动画循环 。动画速度10FPS&#xff0c;修改动画名称idle。 拖动…

数据结构之探索“堆”的奥秘

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 堆的概念 堆的创建 时间复杂度分析&#xff1a; 堆的插入与删除 优先级队列 PriorityQ…

学习大数据DAY23 Linux基本指令4与ngnix安装以及Shell,python编写环境配置

目录 其他扩展类 echo 输出字符串 date 显示当前日期 (用于日期转字符串) date -d 日期解析&#xff08;用于字符串转日期&#xff09; date 设置日期 linux 网络对时 cal 查看日历 wget 命令 seq 命令 Linux 定时执行计划 特殊符号说明 linux 添加硬盘分区挂载 上…

【QT】QT 系统相关(事件、文件、多线程、网络、音视频)

一、Qt 事件 1、事件介绍 事件是应用程序内部或者外部产生的事情或者动作的统称。在 Qt 中使用一个对象来表示一个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本身在不同的时刻发出的。当用户按下鼠标、敲下键盘&#xff0c;或者是窗口需要重新绘制…

初阶数据结构完结 图解所有初阶数据结构 顺序表

1数据结构 1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使 ⽤的 数据结构&#xff0c;常⻅的线性表&#xff1a;顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构&#xff0c;也就说是连…

Centos7_Minimal安装Cannot find a valid baseurl for repo: base/7/x86_6

问题 运行yum报此问题 就是没网 解决方法 修改网络信息配置文件&#xff0c;打开配置文件&#xff0c;输入命令&#xff1a; vi /etc/sysconfig/network-scripts/ifcfg-网卡名字把ONBOOTno&#xff0c;改为ONBOOTyes 重启网卡 /etc/init.d/network restart 网路通了

SSRF中伪协议学习

SSRF常用的伪协议 file:// 从文件系统中获取文件内容,如file:///etc/passwd dict:// 字典服务协议,访问字典资源,如 dict:///ip:6739/info: ftp:// 可用于网络端口扫描 sftp:// SSH文件传输协议或安全文件传输协议 ldap://轻量级目录访问协议 tftp:// 简单文件传输协议 gopher…

Python | TypeError: ‘float’ object is not subscriptable

Python | TypeError: ‘float’ object is not subscriptable 在Python编程中&#xff0c;遇到“TypeError: ‘float’ object is not subscriptable”这一错误通常意味着你尝试对浮点数&#xff08;float&#xff09;使用了下标访问&#xff08;如数组或列表那样的访问方式&a…

Typecho仿百度响应式主题Xaink源码

新闻类型博客主题&#xff0c;简洁好看&#xff0c;适合资讯类、快讯类、新闻类博客建站&#xff0c;响应式设计&#xff0c;支持明亮和黑暗模式 直接下载 zip 源码->解压后移动到 Typecho 主题目录->改名为xaink->启用。 源码下载&#xff1a;https://download.csdn…