【java】图书管理系统

  • 完整代码链接:https://gitee.com/zeng-xuehui/Java_repository/tree/master/test_11_27_1/src
  • 我们在写这个系统时,首先需要搭建框架,再实现业务逻辑;
  • 图书管理系统是用户通过各种功能图书进行操作的一个系统;
  • 我们需要通过三方面进行编写代码:1、用户  2、功能 3、图书,所以代码大的分为了这三部分;

1、代码主要就分为三大模块和一个Main类来测试图书管理系统;


2、 book包中的Book类和BookList类

Book类:是用来描述书这个对象的;

BookList类:用来描述书架上的书;

Book类代码:

package book;public class Book {// book的属性private String name; // 名字private String author; // 作者private int price; // 价格private String type; // 类型private Boolean isBorrow = false; // 是否借阅->初始值false// 如果这里不初始化,后面有些地方使用到isBorrow这个属性就会报错;// 书的初始化public Book() {}public Book(String name, String author, String type, int price) {this.name = name;this.author = author;this.type = type;this.price = price;}// 方法public void setBorrow(Boolean isBorrow) {this.isBorrow = isBorrow;}public String getName() {return name;}public String getAuthor() {return author;}public int getPrice() {return price;}public String getType() {return type;}public Boolean getBorrow() {return isBorrow;}public void setName(String name) {this.name = name;}public void setAuthor(String author) {this.author = author;}public void setType(String type) {this.type = type;}public void setPrice(int price) {this.price = price;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +", type='" + type + '\'' +((isBorrow == true)? " 已借阅":" 未借阅") +'}';}
}

BookList类代码:

package book;/*** 难点:数组的初始化、数组应该如何使用* 1、this.books = new Book[10]; // 将书架初始化为10,可以存放10本书**/public class BookList {// 存放书本private Book[] books; // 这是书架,存放书本private int useSize; // 存放数量// 初始化public BookList() {this.books = new Book[10]; // 将书架初始化为10,可以存放10本书// 书架上有两本书,所以可以通过实例代码块实现,或者构造代码块实现this.books[0] = new Book("java","高斯林","编程",32);this.books[1] = new Book("C语言","xxxx","编程",45);this.useSize = 2; // 书架上有两本书}public Book getBooks(int pos) {return this.books[pos];// 这里返回的是一本书,所以返回值是Book}public void setBook(Book book, int pos) {// 书架上新增一本书,新增到哪个位置this.books[pos] = book;}public int getUseSize() {return useSize;}public void setUseSize(int useSize) {this.useSize = useSize;}
}

 

3、 user包中的User类、Administractor类、OrdinaryUser类

User类:用来描述用户这个对象的;

Administractor类:主要写的是管理员用户的特有方法和属性;

OrdinaryUser类:主要写的是普通用户的特有方法和属性;

在这里的有一个难点:我最初写的时候不理解功能数组的初始化

User类代码:

package user;import book.BookList;
import function.Function;/***  难点:在用户中定义功能数组*  1、protected Function[] functions; // 数组并没有初始化,没有为数组分配空间*/public abstract class User {protected Function[] functions; // 数组并没有初始化,没有为数组分配空间//用户属性private String name; // 这是用户的姓名public User(String name) {this.name = name;}// 方法public abstract int menu();// 功能实现的方法public void function(int choose, BookList bookList) {// this.functions[] -> 这是一个功能对象// this.functions[choose].work() -> 调用对象中的方法// this.functions[choose].work(bookList);// 接口不能new,但是接口可以引用对象,这里接口是应用的对象Function function = this.functions[choose]; // 这是功能对象function.work(bookList);}
}

 Administractor类代码:

package user;import function.*;import java.util.Scanner;/*** 难点:功能数组初始化* // this既可以调用子类的成员,也可以调用父类的成员*         this.functions = new Function[]{*                 new ExitSystem(),*                 new AddFunction(),*                 new ReturnFunction(),*                 new DeleteFunction(),*                 new ShowFunction()*         };* 难点:选择功能之后为什么没有实现对应的功能*/public class Administrator extends User{public Administrator(String name) {super(name);// this既可以调用子类的成员,也可以调用父类的成员this.functions = new Function[]{new ExitSystem(),new AddFunction(),new ReviseFunction(),new DeleteFunction(),new ShowFunction()};}@Overridepublic int menu() {System.out.println(".........管理员.........");System.out.println("0、退出系统");System.out.println("1、增加图书");System.out.println("2、修改图书");System.out.println("3、删除图书");System.out.println("4、显示图书");System.out.println(".......................");System.out.print("请选择功能:");Scanner scanner = new Scanner(System.in);int choose = scanner.nextInt();return choose;}
}

 OrdinaryUser类代码:

package user;import function.*;import java.util.Scanner;/*** 难点:数组的初始化* // this既可以调用子类的成员,也可以调用父类的成员*         this.functions = new Function[]{*                 new ExitSystem(),*                 new BorrowFunction(),*                 new ReturnFunction(),*                 new ShowFunction()*         };* 难点:选择功能之后为什么没有实现对应的功能*/public class OrdinaryUser extends User{public OrdinaryUser(String name) {super(name);// this既可以调用子类的成员,也可以调用父类的成员this.functions = new Function[]{new ExitSystem(),new BorrowFunction(),new ReturnFunction(),new ShowFunction(),new FindFunction()};}// 方法@Overridepublic int menu() {System.out.println("........普通用户........");System.out.println("0、退出系统");System.out.println("1、借阅图书");System.out.println("2、归还图书");System.out.println("3、显示图书");System.out.println("4、查找图书");System.out.println(".......................");System.out.print("请选择功能:");Scanner scanner = new Scanner(System.in);int choose = scanner.nextInt();return choose;// 选择之后为什么没有实现功能呢?}
}

 

 4、function包中的各种操作类和一个Function接口

操作类:管理员的操作类、普通用户的操作类;

Function接口:通过操作类实现这个Function接口,目的就是使操作分离;

 Function接口代码:

package function;import book.BookList;public interface Function {// 这些功能都是对书架上的书进行操作// 所以在操作时需要将书架传过来void work(BookList bookList);
}

 操作类代码:

新增图书代码:

package function;import book.Book;
import book.BookList;import java.util.Scanner;public class AddFunction implements Function{@Overridepublic void work(BookList bookList) {System.out.println("增加图书");Scanner scanner = new Scanner(System.in);System.out.print("请输入新增图书书名:");String name = scanner.nextLine();System.out.print("请输入新增图书作者:");String author = scanner.nextLine();System.out.print("请输入新增图书类型:");String type = scanner.nextLine();System.out.print("请输入新增图书价格:");int price = scanner.nextInt();// 新增了书本,所以我们需要构造出一个书的对象Book book = new Book(name, author, type, price);// 新增图书所放的位置// 可以放在数组的开头,也可以放在数组的中间,还可以放在数组的末尾// 但是所放的位置,不允许当前位置之前为空!!!前一个位置必须有数据// 但是我们在放这本书之前需要判断书架中是否存在这本书for (int i = 0; i < bookList.getUseSize(); i++) {Book systemBook = bookList.getBooks(i);if(systemBook.getName().equals(name)) {System.out.println("书架中已存在此书,新增失败!");return ;}}// 走到这里说明书架上没有这本书,新增成功// 但是我们应该怎么在书架中新增呢?// 将书放到数组中的某个下标就新增成功bookList.setBook(book, bookList.getUseSize());bookList.setUseSize(bookList.getUseSize() + 1);System.out.println("新增成功!");}
}

 借阅图书代码:

package function;import book.Book;
import book.BookList;import java.util.Scanner;/*** 发现一个问题:借阅图书和归还图书都没有实际的操作,并没有使书架上的书减少,仅仅只是显示借阅和归还* 借阅、归还图书操作并没有改变书架上的书*/public class BorrowFunction implements Function{@Overridepublic void work(BookList bookList) {System.out.println("借阅图书");System.out.print("请输入借阅图书的书名:");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();// 再进行比较,存在这本书、不存在这本书;int i = 0;for (i = 0; i < bookList.getUseSize(); i++) {if(bookList.getBooks(i).getName().equals(name)) {// 进入这里面说明书架中有这本书bookList.getBooks(i).setBorrow(true);System.out.println("借阅成功!");return; // 这里直接return,下面就不需要再进行判断}}System.out.println("图书中没有这本书:" + name);}
}

 删除图书代码:

package function;import book.Book;
import book.BookList;import java.util.Scanner;public class DeleteFunction implements Function{@Overridepublic void work(BookList bookList) {System.out.println("删除图书");int index = -1; // 用来记录要删除图书的下标System.out.print("请输入要删除图书书名:");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();int i = 0;for (i = 0; i < bookList.getUseSize(); i++) {// 先找到对应下标的书Book book = bookList.getBooks(i);if(book.getName().equals(name)) {// 走到这儿说明已经找到了这本图书// 当找到这本书就跳出循环// 将找到书的下标给到indexindex = i;break;}}// 走到这里说明在书架中没有找到这本书if(i >= bookList.getUseSize()) {System.out.println("书架中没有要删除的这本书!");return ; // 结束当前这个方法}// 如何删除一本书,先在已经有了这本书的下标index// 这里还需要考虑的是j小于多少,如果不减1的话会出现数组越界for (int j = index; j < bookList.getUseSize()-1; j++) {// 写到这里,怎么调用数组呀?// 现在通过getBooks这个方法拿到了j+1位置处的下标Book book = bookList.getBooks(j+1);// 现在这个setBook方法,将book这本书放到j位置bookList.setBook(book,j);}// 还需要将最后没有使用的对象置为空bookList.setBook(null, bookList.getUseSize()-1);bookList.setUseSize(bookList.getUseSize()-1);}
}

 退出系统代码:

package function;import book.BookList;public class ExitSystem implements Function{@Overridepublic void work(BookList bookList) {System.out.println("退出系统");System.exit(0);// 应该要对bookList手动回收}
}

查找图书代码:

package function;import book.Book;
import book.BookList;import java.util.Scanner;public class FindFunction implements Function{@Overridepublic void work(BookList bookList) {System.out.println("查找图书");// 查找图书需要输入查找内容System.out.print("请输入要查找的图书书名:");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();// 输入的数需要与书架上的书进行对比// 难点:怎么和书架上的书进行比较// 现在就是要遍历书架上的书// 每遍历一次就要拿到一本书// 拿到一本书后返回它的下标进行比较for (int i = 0; i < bookList.getUseSize(); i++) {// Book book = bookList[i];// 这样写是错的,bookList是一个类,类中的Book对象才是一个数组// 由于Book数组对象是一个私有的对象,所以需要提供一个方法来获取到i下标的对象Book book = bookList.getBooks(i);// 上面是查找的书名,所以比较的也是书名,需要获取到当前下标的书名if(book.getName().equals(name)) {System.out.print("存在这本书,信息如下:");// 还有这里为什么直接就调用了Book类中的toString方法呢?System.out.println(book);return ; // 当我们找到了就要结束这个方法}}System.out.println("没有你要找的书:" + name);}
}

 归还图书代码:

package function;import book.BookList;import java.util.Scanner;public class ReturnFunction implements Function{@Overridepublic void work(BookList bookList) {System.out.println("归还图书");System.out.print("请输入要归还图书的书名:");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();// 再进行比较,存在这本书、不存在这本书;int i = 0;for (i = 0; i < bookList.getUseSize(); i++) {if(bookList.getBooks(i).getName().equals(name)) {// 进入这里面说明书架中有这本书bookList.getBooks(i).setBorrow(false);System.out.println("归还成功!");return; // 这里直接return,下面就不需要再进行判断}}System.out.println("图书中没有要归还的这本书:" + name);}
}

 修改图书代码:

package function;import book.Book;
import book.BookList;import java.util.Scanner;public class ReviseFunction implements Function{@Overridepublic void work(BookList bookList) {System.out.println("修改图书");// 请输入要修改的图书System.out.print("请输入要修改的图书:");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();// 判断书架上是否有这本书for (int i = 0; i < bookList.getUseSize(); i++) {Book book = bookList.getBooks(i);if(book.getName().equals(name)) {// 走到这里说明书架上有这本书System.out.print("请输入要修改的图书的书名:");String bookName = scanner.nextLine();book.setName(bookName);System.out.print("请输入要修改的图书的作者:");String bookAuthor = scanner.nextLine();book.setAuthor(bookAuthor);System.out.print("请输入要修改的图书的类型:");String bookType = scanner.nextLine();book.setType(bookType);System.out.print("请输入要修改的图书的价格:");int bookPrice = scanner.nextInt();book.setPrice(bookPrice);System.out.println("修改成功!");return;}}System.out.println("书架上没有要删除的这本书:" + name);}
}

 显示图书代码:

package function;import book.Book;
import book.BookList;public class ShowFunction implements Function{@Overridepublic void work(BookList bookList) {System.out.println("显示图书");// 显示图书就是拿到一本书的下标就打印一本书for (int i = 0; i < bookList.getUseSize(); i++) {// 先拿到这本书的下标Book book = bookList.getBooks(i);System.out.println(book);}}
}

 

5、Main类测试图书管理系统

Main类代码:

import book.Book;
import book.BookList;
import function.Function;
import user.Administrator;
import user.OrdinaryUser;
import user.User;import java.util.Scanner;/***  * 1、找对象、创建对象、实现对象*  * 2、最容易想到的两个对象->书、人*  * 3、实现书这个对象,但是书不止一本,所以需要书架*  * 4、书架是用来存放书的,其中涉及的数组是难点(!)*  * 5、操作人员->普通用户、管理员用户*  * 6、不用的用户所提供的操作不相同,如何实现各自操作的分离*  * 7、每一个操作都写成一个类当中,每一个类都是对书进行操作,将这个对书的操作写成一个接口,每个类再去实现接口中的方法*  * 8、实现一个接口数组,一个是普通用户的操作接口数组,一个书管理员用户的操作接口数组,这样就将各自的操作分离了出来,目的就是为了类型统一*  * 9、用户是一个类,用户的基本信息应该包含;但是用户分为->普通用户、管理员用户;这两个类是用户类的子类;这三个类应该如何协同操作呢?*  * 10、我们需要一个登录页面进行操作*/
public class Main {public static User login() {System.out.print("请输入你的姓名:");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();System.out.println("请选择你的身份:1、管理员用户 2、普通用户");int choose = scanner.nextInt();if(choose == 1) {return new Administrator(name);}else {return new OrdinaryUser(name);}}public static void main(String[] args) {BookList bookList = new BookList();// 登录页面User user = login();while(true) {// 循环操作int choose = user.menu(); // 返回了一个功能选择,所以需要接收// 难点:那么需要怎样调用这些功能呢?user.function(choose,bookList);}}
}

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

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

相关文章

【腾讯地图】【微信小程序】地图选点

【相关文章】 【腾讯地图】【微信小程序】地图选点 【腾讯地图】【微信小程序】路线规划 【腾讯地图】【微信小程序】城市记录&#xff08;基于地图选点入门版&#xff09; 【效果展示】 【官方文档】 微信小程序插件-地图选点插件 【完善流程】 当前操作和官方文档操作有部…

36 - 电商系统表设计优化案例分析

如果在业务架构设计初期&#xff0c;表结构没有设计好&#xff0c;那么后期随着业务以及数据量的增多&#xff0c;系统就很容易出现瓶颈。如果表结构扩展性差&#xff0c;业务耦合度将会越来越高&#xff0c;系统的复杂度也将随之增加。这一讲我将以电商系统中的表结构设计为例…

vue2+element-ui npm run build打包后,在服务器打开报错

报错 页面的图标也显示不出来&#xff0c;如下 解决&#xff1a; 在build->utils.js文件里面加上publicPath: ../../&#xff0c;再打包发布一下就可以了 // Extract CSS when that option is specified// (which is the case during production build)if (options.extrac…

Spring Cloud Stream如何屏蔽不同MQ带来的差异性?

引言 在当前的微服务架构下&#xff0c;使用消息队列&#xff08;MQ&#xff09;技术是实现服务解耦和削峰填谷的重要策略。为了保证系统的灵活性和可替换性&#xff0c;我们需要避免对单一开源技术的依赖。 市面上有多种消息队列技术&#xff0c;如 Kafka、RocketMQ、Rabbit…

思维模型 达维多定律

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。持续创新&#xff0c;引领市场潮流。 1 达维多定律的应用 1.1 达维多定律应用之吉列公司&#xff1a;不断创新的刀片领导者 吉列公司是一家以剃须刀片而闻名的公司。自 1901 年推出首款安…

【开源视频联动物联网平台】开箱即用的物联网项目介绍

写一个开箱即用的物联网项目捐献给Dromara组织 一、平台简介 MzMedia开源视频联动物联网平台&#xff0c;简单易用&#xff0c;更适合中小企业和个人学习使用。适用于智能家居、农业监测、水利监测、工业控制&#xff0c;车联网&#xff0c;监控直播&#xff0c;慢直播等场景。…

【Spring Boot 源码学习】BootstrapRegistryInitializer 详解

Spring Boot 源码学习系列 BootstrapRegistryInitializer 详解 引言往期内容主要内容1. 初识 BootstrapRegistryInitializer2. 加载 BootstrapRegistryInitializer3. BootstrapRegistryInitializer 的初始化 总结 引言 书接前文《初识 SpringApplication》&#xff0c;我们从 …

谈一谈大小端

文章目录 一&#xff0c;什么是大小端二&#xff0c;为什么有大小端三&#xff0c;怎么验证大小端 一&#xff0c;什么是大小端 大端存储模式&#xff1a;是指数据的地位存储在高地址处&#xff0c;数据的高位存储在低地址处。 小端存储模式&#xff1a;是指数据的低位存储在低…

从0开始学习JavaScript--JavaScript 单例模式

单例模式是一种常见的设计模式&#xff0c;它保证一个类仅有一个实例&#xff0c;并提供一个全局访问点。在 JavaScript 中&#xff0c;单例模式通常用于创建唯一的对象&#xff0c;以确保全局只有一个实例。本文将深入探讨单例模式的基本概念、实现方式&#xff0c;以及在实际…

矩阵代数与MATLAB实现(特征值、广义特征值、酋矩阵、)

矩阵代数的相关知识 目录 一、特征值与特征向量 1、特征值与特征向量 2、MATLAB计算 二、广义特征值与广义特征向量 1、广义特征值与广义特征向量 2、MATLAB计算 三、酋矩阵 1、酋矩阵 2、MATLAB计算 四、未完待续 总结 提示&#xff1a;以下是本篇文章正文内容&…

Pytorch从零开始实战11

Pytorch从零开始实战——ResNet-50V2算法实战 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——ResNet-50V2算法实战环境准备数据集模型选择开始训练可视化总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pyt…

VUE语法-ref和reactive响应式数据引用

1、响应式概述 在vue中定义一个参数&#xff0c;当这个参数在使用中发生了变化&#xff0c;在页面中对这个数据应用的地方都会同步的发生变化&#xff0c;这个就是数据响应式。 2、创建一个非响应式的参数 该程序中采用的是VUE3的用法&#xff1a; 1、在程序中定义了一个局…

GraphCast:基于机器学习的全球中期天气预测模型

文章信息 文章题为”GraphCast: Learning skillful medium-range global weather forecasting”&#xff0c;该文章于2023年发表至Science&#xff0c;文章内容主要关于利用机器学习模型&#xff0c;实现高效、准确的全球中期天气预测。由于文章内容较多&#xff0c;本文仅对研…

力扣刷题篇之分治

系列文章目录 目录 系列文章目录 前言 一、分解问题 二、解决子问题 三、合并结果 总结 前言 刷题按照&#xff1a; [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 - 力扣&#xff08;LeetCode&#xff09; 参考&#xff1a; 「五大常用算法」一文搞懂分治算法…

大数据HCIE成神之路之数学(4)——最优化实验

最优化实验 1.1 最小二乘法实现1.1.1 算法介绍1.1.2 代码实现1.2 梯度下降法实现1.2.1 算法介绍1.2.2 代码实现1.3 拉格朗日乘子法1.3.1 实验1.3.2 实验操作步骤1.1 最小二乘法实现 1.1.1 算法介绍 最小二乘法(Least Square Method),做为分类回归算法的基础,有着悠久的历…

第20章:多线程

20.1 线程简介 在Java中&#xff0c;并发机制非常重要&#xff0c;程序员可以在程序中执行多个线程&#xff0c;每个线程完成一个功能&#xff0c;并与其他线程并发执行&#xff0c;这种机制被称为多线程。但是&#xff0c;并不是所有编程语言都支持多线程。 线程的特点&#…

visual studio 2022 更改字体和大小

工具--->选项 文本编辑器 输出窗口

Linux系统之uptime命令的基本使用

Linux系统之uptime命令的基本使用 一、uptime介绍二、uptime命令使用帮助2.1 uptime的help帮助信息2.2 uptime的语法解释 三、uptime的基本使用3.1 直接使用uptime命令3.2 显示uptime版本信息3.3 显示系统运行时间3.4 显示系统最后一次启动时间 四、uptime命令的使用注意事项 一…

基于YOLOv8深度学习的生活垃圾分类目标检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

C++前缀和算法的应用:优化了6版的1324模式

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 本题其它解法 C前缀和算法的应用&#xff1a;统计上升四元组 类似题解法 包括题目及代码C二分查找算法&#xff1a;132 模式解法一枚举3C二分查找算法&#xff1a;…