图书管理系统

  ❤️❤️前言~🥳🎉🎉🎉

hellohello~,大家好💕💕,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏💞 💞 关注💥💥,如果发现这篇文章有问题的话,欢迎各位评论留言指正,大家一起加油!一起chin up!👍👍 

💥个人主页:E绵绵的博客
💥所属专栏:JAVASE题目练习  JAVASE知识点专栏  c语言知识点专栏   c语言题目练习

      现在我们将把之前学过的知识点总结做成一个小项目 ,叫图书管理系统,来看一下吧。 

 设计思路

 我们在设计系统前要遵循面向对象的原则:

1.找到对象

2.创建对象

3.使用对象

所以我们需要先理清自己的思绪,想明白需要创建的对象和需要实现的功能。

 

1. 首先,想清楚系统的界面。系统对于图书管理员来说是管理系统,对于普通用户来说是服务系统。所以我们针对管理员和普通用户所展示的界面是不同的。

 2.书的属性有书名,作者,价格,类型,是否被借出。所以我们可以将书的属性进行封装,同时设置一个书架类,用于存放书籍。设置一个书的数组可以解决。

3.管理员界面上,我们可以添加书籍,查找书籍,删除书籍,显示书籍和退出系统。

4.普通用户界面上,我们可以查找书籍,借阅书籍,归还书籍和退出系统。

5.所以我们可以将这些操作封装起来,设计成单独的类,但可以通过一些操作将这些功能分成两部分。

书籍和书架

  ❤️❤️首先我们面对对象时,找对象书肯定是一个对象,所以我们创建跟书有关的对象,如书和书架。现在我们就先来创建这两个对象吧:

书(Book)

❤️❤️我们创建一个book的包,用于存放与书有关的类。根据上述思路,我们可以在Book包中创建一个Book的类和一个Booklist (书架) 的类。首先创建一个book类,在book中写入书的有关属性,书名 (name) ,作者 (author)  ,价格 (price)  ,类型 (type) 以及是否被借出。我们通过封装,将属性前的访问修饰符设置为private权限,然后通过提供相应的get方法和set方法以及一个不包含是否被借出的构造方法(我们将是否被借出属性的类型设置为boolean,因为Boolean类型默认为false,所以可以不初始化),然后通过快捷键提供相应的toString方法的重写。

注意这些方法很多都能通过快捷键去生成,代码如下:

public class Book {private String name;private String  author;private  String  type;private  int   price;private   boolean  isborrowed;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 String getType() {return type;}public void setType(String type) {this.type = type;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}

之所以用private修饰其书的属性,是为了体现书的密封性(书架中的属性也同理)

书架(BookList)

💕💕我们首先设置一个private权限的Book数组books,同时设置一个usedSize的变量,用于记录当前书架上存放了多少本书。我们写一个BookList的构造方法,同时将数组的长度初始化为10,然后通过快捷键设置userSize的getter and setter方法。注意不要使用编译器生成的Book数组books的getter and setter 方法,因为它针对的是books数组,并不是针对数组中存放的书,那并不是我们想要的。所以我们单独设置一个名为pos的数组下标参数,在getter方法中返回books的数组下标pos,在setter方法中,我们将 books数组的pos下标设置为一本书 。这样就能通过这两个方法去访问该数组的书成员。

现在请看以下代码:

public class BookList {private  Book[] books;private  int usedsize;//书架上目前存放的书量public BookList() {this.books=new Book[10];usedsize=4;this.books[0] = new Book("三国演义","罗贯中",20,"小说");this.books[1] = new Book("西游记","吴承恩",9,"小说");this.books[2] = new Book("红楼梦","曹雪芹",19,"小说");
this.books[3]=new Book("Java","xx",18,"学习资料");}public int getUsedsize() {return usedsize;}public void setUsedsize(int usedsize) {this.usedsize = usedsize;}public Book getBook(int i){return books[i];}public  void   setBook(int i,Book book){books[i]=book;}
}

这里的属性也是用private修饰,呈封装性。

 用户

💕💕 除此之外,除了书是对象,图书管理系统也要人使用对吧,所以人也是个对象。并且因为身份的不同,分为普通用户和管理员。而又因为都是人,所以会有一些相同点。所以我们就创建一个子类user ,两个父类。

user(用户抽象类)(子类) 

💕💕在普通用户和管理员用户中存在许多共性,因此我们这里设置一个抽象类供普通用户和管理员用户来继承使用,并且将其变为抽象类更方便继承。

abstract public class User {protected String name;protected IOperation[] iOperations;abstract public   int  menu();public User(String name) {this.name = name;}public  void useoperation(int choice,BookList bookList){IOperation iOperation = iOperations[choice];iOperation.work(bookList);}
}

 管理员类(Administrator)

💕💕我们设置管理用户的菜单,再对应着菜单在构造方法中设置接口类型的数组的具体操作

​
public class Administrator extends User{public Administrator(String name) {super(name);iOperations = new IOperation[]{new ExitOperation(),new FindOperation(), new AddOperation,new DeleteOperation(),new ShowOperation()};}@Overridepublic 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;}
}​

 普通用户(NormalUser)

💕💕它和管理员类的操作大致相同,这里就不过多讲述了,直接上代码

​
public class NormalUser extends User {public NormalUser( String name){super(name);iOperations=new IOperation[] {new ExitOperation(),new FindOperation(),new BorrowOperation(),new RetrunOperation()};}public 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;}}​

 对书籍的相关操作

❤️❤️我们知道面对对象分为三步,最后一步是使用对象,而这里就是对于对象的使用。其中有很多操作,我们来看一下吧。

操作接口(IOperation)

❤️❤️所有的操作都是要对于书架进行操作的,所以我们在这里提供一个接口供不同操作来实现,并且给他们传入书架类的参数,代码如下:

​
public interface IOperation {public void work(BookList bookList);
}​

 借阅图书(BorrowOperation

❤️❤️首先,我们需要让用户输入想要借阅的图书的名字,然后我们挨个遍历书架上的书,如果有,那就可以借,将书籍的借阅状态改为true就可以,如果没有就告诉用户没有此书,无法借阅。

public class BorrowOperation implements IOperation{@Override
public 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 ((bookList.getBook(i).getName()).equals(name)){if(bookList.getBook(i).getIsborrowed()==true) {System.out.println("该书已被借出,现在没有这本书");return;}else {System.out.println("该书借出后请及时归还");bookList.getBook(i).setIsborrowed(true);return;}}if(i== bookList.getUsedsize()-1){System.out.println("未查找到该书");}}}
}

归还图书(ReturnOperation)

 ❤️❤️和借阅图书思路相似,这里不多说了。直接上代码:

public class RetrunOperation implements  IOperation {@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 ((bookList.getBook(i).getName()).equals(name)) {bookList.getBook(i).setIsborrowed(false);System.out.println("该书归还成功");return;}}System.out.println("不存在该书");}
}

 查找图书(FindOperation)

❤️❤️ 查找功能和遍历类似,只要利用equals关键字比较字符串输出就行。在 Findioperation 类中,先输入要查找的书名,遍历所有的书,比较书名,书名一样输出即可。 

public class FindOperation implements IOperation {@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 ((bookList.getBook(i).getName()).equals(name)) {System.out.println("找到该书");System.out.println(bookList.getBook(i));return;}}System.out.println("没找到该书");}
}

显示图书 (ShowOperation)

❤️❤️ 遍历整个书架,然后挨个打印输出图书信息就可以了。

public class ShowOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("该操作进行中,将展示所有书的信息");for (int i = 0; i < bookList.getUsedsize() ; i++) {System.out.println(bookList.getBook(i));}
}}

 添加图书(AddOperation)

❤️❤️首先,我们需要让用户输入想要添加的图书的相关信息,然后我们为用户输入的图书新建一个对象,接下来就是合法性判断,我们拿刚才新建的图书对象和书架上的每一个图书对象进行遍历对比,如果没有重复的图书就可以存入这本书,要存入这本书就调用刚才书架类中提供的方法setBooks,在新加一本书籍后,对应的书籍数量也得增加,也就是调用setUesdSize方法来增加书籍的数量。

public class AddOperation implements IOperation {@Overridepublic void work(BookList bookList) {System.out.println("该操作进行中,请输入要添加的书");Scanner scanner = new Scanner(System.in);System.out.println("请输入书名");String name = scanner.nextLine();if(bookList.getUsedsize()==10) {System.out.println("书架满了,无法添加");return;}for (int i = 0; i < bookList.getUsedsize(); i++) {if ((bookList.getBook(i).getName()).equals(name)) {System.out.println("该书在书架中已有,无需添加");return;}}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.setBook(bookList.getUsedsize(),book );System.out.println("添加成功");bookList.setUsedsize(bookList.getUsedsize()+1);
}}

这里有个重要的点,对于新建对象时的输入,必须nextint在最后面,否则会导致以下现象。

这里只接受了三个,第四个还没输入就结束了。所以应该把nextint放在最后,这样就不会有异常现象。

对于其原因,这里有篇文章可以解释以上现象java中程序逻辑控制-CSDN博客,在这部分有提到过该现象。

删除图书 (DeleteOperation)

❤️❤️思路:首先找到有没有这本书,如果找到了,这书后边的书就从后往前直接覆盖掉之前的书数据,然后将usedsize减一就行了,从而最后一个数据我们就使用不了(之后的其他操作会将最后一个数据覆盖掉)。

所以在循环时,i 要小于usedSize - 1,,如果大于等于usedsize-1的话,就会越界访问数组之外的数据,从而报错。

public class DeleteOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("该操作进行中,请输入要删除的书");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();int deletesize=0;for (int i = 0; i < bookList.getUsedsize(); i++) {if ((bookList.getBook(i).getName()).equals(name)) {deletesize=i;break;}if(i== bookList.getUsedsize()-1){System.out.println("该书架中不存在该书");return;}}for (int i = deletesize; i < bookList.getUsedsize()-1 ; i++) {bookList.setBook(i,bookList.getBook(i+1));}bookList.setUsedsize(bookList.getUsedsize()-1);System.out.println("删除"+name+"成功");}}

退出系统 

❤️❤️最简单的一个操作,System.exit(0)代表着结束程序,所以我们只需要使用该方法就能退出系统。

public class ExitOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("系统已退出");System.exit(0);//作用是结束该程序}
}

 main类

所以有了前面的这些基础,我们就将它们组合起来利用,形成这个main类。

我们在main类中除了有main方法外,还要设置一个登录程序的方法,登录管理员我们就新建一个管理员对象,登录普通用户我们就新建一个普通用户对象,然后我们根据用户的输入来调用我们菜单中的选项,我们通过设置接口数组从而来操作它。

public class Main {public static User login() {System.out.println("请输入你的名字");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();System.out.println("请确认你的身份  1:普通用户 2:管理员 ");while (true) {int choice = scanner.nextInt();if (choice == 1) {return new NormalUser(name);} else if (choice == 2) {return new Administrator(name);} else {System.out.println("只能输入1或2,请重新输入");continue;}}}public static void main(String[] args) {BookList bookList=new BookList();User  user =login();while (true){int choice= user.menu();user.useoperation(choice,bookList);
}
}

总结 

 所以这就是我们的图书管理系统,如果想看完整的代码,我这里有我码云的链接,大家可以看一下:

_2024_4_6/src · Eason绵绵/JAVASE代码仓库 - 码云 - 开源中国 (gitee.com)

本篇文章制作不易,还请各位大佬给个三连,点点关注,点点赞,评评论,谢谢各位大佬们呀,一起加油❤️❤️~🥳🎉🎉🎉

​​​​​​​

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue - 你会在同一个元素上使用v-for和v-if吗

难度级别:初级及以上 提问概率:50% 在初学者看来,v-for和v-if同时使用是非常方便的,二者共同使用的常见场景有两种。例如有两个列表,分别用于渲染学生数据和老师数据,然后有两个单选按钮,用于切换当前页面中需要展示学生列表还是老师列…

鸿蒙HarmonyOS 与 Android 的NDK有什么不一样?

1. 序言 就像开发Android要用Android Studio一样&#xff0c;Android Studio&#xff08;简称AS&#xff09;其实是基于IDEAgradle插件android插件开发而来。 鸿蒙系统&#xff0c;你可以认为它和android有点像&#xff0c;但又是超越android的存在&#xff0c;除了手机&…

笛卡尔树[天梯赛二叉树专项训练]

文章目录 题目描述思路AC代码 题目描述 输入样例1 6 8 27 5 1 9 40 -1 -1 10 20 0 3 12 21 -1 4 15 22 -1 -1 5 35 -1 -1 输出样例1 YES 输入样例2 6 8 27 5 1 9 40 -1 -1 10 20 0 3 12 11 -1 4 15 22 -1 -1 50 35 -1 -1 输出样例2 NO思路 见注释 AC代码 #include <bits/st…

搭建python编译环境

目录 1.安装依赖包 2.安装失败进行换源 3. 更新系统 通过C 语言调用 Python 代码&#xff0c;需要先安装 libpython3 的 dev 依赖库&#xff08;不同的 ubuntu 版本下&#xff0c; python 版本 可能会有差异&#xff0c; 比如ubuntu 22.04 里是 libpython3.10-dev &#xff09…

2024/4/1—力扣—最小高度树

代码实现&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ struct TreeNode* buildTree(int *nums, int l, int r) {if (l > r) {return NULL; // 递归出口}struct…

[StartingPoint][Tier1]Sequel

Task 1 During our scan, which port do we find serving MySQL? (在扫描过程中&#xff0c;我们发现哪个端口为 MySQL 提供服务&#xff1f;) 3306 Task 2 What community-developed MySQL version is the target running? (目标正在运行哪个社区开发的 MySQL 版本&…

Python实现【坦克大战】+源码分享

写在前面&#xff1a; 坦克大战&#xff0c;这款经典的电子游戏&#xff0c;无疑是许多80后和90后心中不可磨灭的童年记忆。它不仅仅是一款游戏&#xff0c;更是那个时代科技娱乐方式的缩影&#xff0c;见证了电子游戏行业的起步与发展。 在那个电脑和网络尚未完全普及的年代…

c语言实现2048小游戏

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h>int best 0 ;// 定义2048游戏的结构体 typedef struct { int martix[16]; // 当前4*4矩阵的数字 int martixPrior[16]; // 上一步的4*4矩阵的数字 int emptyIndex[16…

LeetCode 1017. 负二进制转换

解题思路 相关代码 class Solution {public String baseNeg2(int n) {if(n0) return "0";String s"";while(n!0)if(Math.abs(n)%20){nn/(-2);ss0;}else{ss1; n (n-1)/(-2);}String t reverse(s);return t;}public String reverse(String s){Str…

前端三剑客 —— JavaScript (第一节)

目录 回顾内容 1.弹性布局 2.网格布局 JavaScript 概述 发展 浏览器 什么是Javascript JavaScript 能干什么 JavaScript需要的环境 JavaScript初体验 基本数据 JS书写方式 行内JS 页面JS 外部JS 1&#xff09;创建外部JS文件 2&#xff09;编写页面 对话框 警…

【Threejs进阶教程-效果篇】1.Threejs文字与css2d/css3d技术

Threejs文字与css2d/css3d技术 学习ThreeJS的捷径学习之前先搞清楚自己想要什么样的效果贴图文字准备一张带文字的png贴图使用sprite来进行贴图实现2D始终面朝相机的文字使用planeGeometry来贴图实现3D文字使用planeGeometry来贴图实现伪3D文字动态贴图文字html2Canvas 文字几何…

操作系统复习

虚拟内存 内存(memory)资源永远都是稀缺的&#xff0c;当越来越多的进程需要越来越来内存时&#xff0c;某些进程会因为得不到内存而无法运行&#xff1b; 虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存&#xff0c;而实际上&#xff0…

HTML基础知识详解(下)(如果想知道html的全部基础知识点,那么只看这一篇就足够了!)

前言&#xff1a;在上一篇文章中&#xff0c;我们已经学习完了超链接标签、列表标签和表格标签&#xff0c;但是我们还有一些标签没有学习&#xff0c;在这篇文章中&#xff0c;我们将学习剩余的标签。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页…

JAVA并发编程(一)

JAVA并发编程&#xff08;一&#xff09; 1.1JAVA线程API 1.1.1currentThread package com.lisus2000.thread;/** * 当前线程 * */ public class Test07 extends Thread {public Test07() {System.out.println("new Test07()......" Thread.currentThread().getNa…

vivado中移位寄存器的优化(二)

移位寄存器优化用于改善移位寄存器单元&#xff08;SRLs&#xff09;与其他逻辑单元之间的负裕量路径的时序。如果存在对移位寄存器单元&#xff08;SRL16E或SRLC32E&#xff09;的时序违规&#xff0c;优化会从SRL寄存器链的开始或结束位置提取一个寄存器&#xff0c;并将其放…

深入理解数据结构第三弹——二叉树(3)——二叉树的基本结构与操作

二叉树&#xff08;1&#xff09;&#xff1a;深入理解数据结构第一弹——二叉树&#xff08;1&#xff09;——堆-CSDN博客 二叉树&#xff08;2&#xff09;&#xff1a;深入理解数据结构第二弹——二叉树&#xff08;2&#xff09;——堆排序及其时间复杂度-CSDN博客 前言…

面试:HashMap

目录 1、底层数据结构&#xff0c;1.7 与1.8有何不同? 2、为何要用红黑树&#xff0c;为何一上来不树化&#xff0c;树化阈值为何是8&#xff0c;何时会树化&#xff0c;何时会退化为链表? 3、索引如何计算? hashCode都有了&#xff0c;为何还要提供hash()方法?数组容量为…

【Easy云盘 | 第十二篇】分享模块(获取分享信息、校验分享码、获取文件列表)

文章目录 4.4.4获取分享信息4.4.5校验分享码4.4.6获取文件列表 4.4.4获取分享信息 明天做 4.4.5校验分享码 明天做 4.4.6获取文件列表 明天做

Vue3大事件项目1 登录注册

创建项目 引入 element-ui 组件库 登录&#xff1a;注册样式准备之后&#xff0c;配置校验规则&#xff08;4个条件&#xff1a;一数据、二规则&#xff09; 1. 校验相关 (1) 给当前表单绑上整个的数据对象&#xff1a;el-form > :model"ruleForm" 绑…

云服务器是不是云盘?

​  云服务器是不是云盘?云服务器和云盘是两个不同的概念&#xff0c;尽管它们都是云计算服务的一部分。云服务器是一种提供计算能力的服务&#xff0c;可以运行各种应用程序和服务&#xff0c;而云盘则是一种提供数据存储和共享服务的工具。 具体来说&#xff1a; 云服务器…