图书管理系统——Java版

news2024/12/23 12:06:24

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏:JavaSE

顺序表的学习,点我 

目录

图书管理系统菜单

基本框架:

书:

书架: 

用户: 

实现基本功能 

新增图书:

借阅图书:

删除图书: 

退出系统: 

查找图书: 

归还图书: 

显示图书:


图书管理系统菜单

上面是根据选择不同用户,从而弹出的不同菜单。 

基本框架:

先把大的框架搭建出来。这里我们要用到三个对象:书、书架、用户。

书:

一些基本属性:

public class Book {
    private String name; // 书名
    private String author; // 作者
    private int price; // 价格
    private String type; // 类型
    private int count; // 数量
    private int lentCount; // 被借出的数量
}

用到private是为了防止所有人都可以拿到这些属性并且修改。

构造方法:

public Book(String name, String author, int price, String type, int count) {
        // 书一直在图书馆中,只有当新增或者删除才变动。而新增的书并不会一下子就被借出
        // 因此不需要初始化被借出的数量
        this.name = name;
        this.author = author;
        this.price = price;
        this.type = type;
        this.count = count;
    }

构造方法是为了在创建一个书的实例(新增)时初始化书的。 

getter 、setter 方法:

// 下面这些方法是用来修改书的状态的
    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 int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getLentCount() {
        return lentCount;
    }

    public void setLentCount(int lentCount) {
        this.lentCount = lentCount;
    }

通过getter、setter方法来访问和修改书的属性。

重写toString 方法:

// 重写toString方法,以便于更好的打印
    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ", count=" + count +
                ", lentCount=" + lentCount +
                '}';
    }

我们后面在查找和显示书时,要把书的全部信息给都给打印出来,因此得重写toString 方法。

书架: 

属性: 

public class BookList {
    // 书架里面原本应该有书才对
    // 书架是用来存放和管理书籍的,可以用顺序表(数组)来写
    private Book[] books = new Book[10]; // 为了方便,只放了3本书
    private int usedSize; // 书架已经使用的长度
}

getter、setter 方法:

    public Book[] getBooks() {
        return books;
    }

    public void setBooks(Book[] books) {
        this.books = books;
    }

    public int getUsedSize() {
        return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }

构造方法:

    // 初始化3本书
    public void func() {
        this.books[0] = new Book("Head First Java",
                "Kathy Sierra 、 Bert Bates",
                79, "计算机", 100);
        this.books[1] = new Book("Java 核心技术 卷I",
                "Cay S. Horstmann",
                119, "计算机", 100);
        this.books[2] = new Book("大话数据结构",
                "程杰", 59, "计算机", 100);
        this.usedSize = 3;
    }

    public BookList() {
        this.func();
    }

构造方法用来初始化书架的,也就是创建书的实例放到书架上。

用户: 

    public abstract class User{
    protected String name; // 因为这个name其子类也得使用
    public User(String name) {
        this.name = name;
    }

因为用户有两种,所以User肯定不能知道是哪一种。因此就用抽象类来写。

普通用户:

public class RegularUsers extends User{
    public RegularUsers(String name) {
        super(name);
    }
}

管理员用户: 

public class Administrators extends User{
    public Administrators(String name) {
        super(name);
    }
}

对象创建完毕,接下来就要开始让对象之间进行交互了。

前面我们看到了,不同的用户,根据选择的不同,会弹出不同功能菜单。这个有没有一种很熟悉的感觉,没错这就是我们在前面学习的多态。接下来就是要找多态的条件了:子类对象给到父类引用;子类重写父类当中的方法;通过父类引用调用被重写的方法。在上面的分析中,只有用户之间存在父子类关系。那么我们就可以在设计菜单时,根据选择的不同返回不同的用户对象。返回值就用父类接收,父类在调用功能菜单时,根据是哪一个子类,从而会调用不同的菜单。

登录菜单:

    public static User login() {
        System.out.print("请输入您的姓名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();

        System.out.println("请选择您的身份:1. 管理员;2. 普通用户");
        int n = scanner.nextInt();
        // 根据选择的不同,弹出不同的界面 (这里我们就可以采用多态的方式来写)

        while (true) {
            if (n == 1) {
                System.out.println("登录成功!");
                // 如果是管理员就返回管理员对象
                return new Administrators(name);
            }else if (n == 2) {
                System.out.println("登录成功!");
                // 如果是普通用户就返回普通用户对象
                return new RegularUsers(name);
            }else {
                System.out.println("登录失败,请重新选择您的身份!");
                n = scanner.nextInt();
            }
        }
    }

Main 方法: 

    public static void main(String[] args) {
        // 系统登录
        User user = login();
        // 创建一个书架
        BookList bookList = new BookList();
        while (true) {
            // 登录之后,就可以根据前面的选择弹出不同身份的界面
            int choice = user.menu();

            // 根据返回的选择,进行不同对象的不同的操作
            // 对象已经确定了,接下来,就是进行不同的操作。
            // 因为不同的对象包含不同的操作,所以我们可以把这个操作分成一个数组放到不同的类中
            user.work(choice, bookList); // 操作的对象是书架,因此传入书架
        }
    }

根据我们在功能页面的选择,来返回不同的值。接着调用work方法来实现不同的功能。这里同样运用了多态的思想。那么父类和子类同样都要有work方法。 

父类:

public abstract class User{
    protected String name; // 因为这个name其子类也得使用
    public User(String name) {
        this.name = name;
    }
    public abstract int menu();
    public abstract void work(int choice , BookList bookList);
}

子类:

public class RegularUsers extends User{
    protected IWork[] iWorks;
    public RegularUsers(String name) {
        super(name);
        // 注意顺序,要和功能菜单一致
        this.iWorks = new IWork[]{new Exit(), new FindBook(), new BorrowBook(), new ReturnBook()};
    }

    @Override
    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.print("请选择您要进行的操作:");
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
    public void work(int choice, BookList bookList) {
        // 通过对应的参数执行对应的操作
        iWorks[choice].work(bookList);
    }
}
public class Administrators extends User{
    IWork[] iWorks;
    @Override
    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.print("请选择您要进行的操作:");
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }

    public Administrators(String name) {
        super(name);
        // 注意顺序,要和功能菜单一致
        this.iWorks = new IWork[]{new Exit(), new FindBook(), new AddBooks(), new DelBook(), new ShowBook()};
    }

    @Override
    public void work(int choice, BookList bookList) {
        iWorks[choice].work(bookList);
    }
}

因为操作是根据选择来分配的,也是可以用数组来进行接收,并且执行的。 

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

 上面是一个IWork的接口,为了实现用数组接收,并且更好的管理各种功能。

实现基本功能 

下面就是实现各种基本的功能了。

新增图书:

public class AddBooks implements IWork {

    @Override
    public void work(BookList bookList) {
        System.out.println("正在新增图书...");
        // 其实就是在这个顺序表的数组中新增了一个元素
        // 首先,得判断这个数组是否已经满了
        // 使用的长度如果等于书架的长度了,就需要增加书架的长度了
        if (bookList.getBooks().length == bookList.getUsedSize()) {
            System.out.println("书架已满,正在新增书架空间,请稍后...");
            // 创建一个新的数组
            Book[] newArray = Arrays.copyOf(bookList.getBooks(),2*bookList.getBooks().length);
            bookList.setBooks(newArray);
            System.out.println("书架空间新增成功!");
        }
        System.out.println("请输入要新增的书名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("请输入要新增的书的作者:");
        String author = scanner.nextLine();
        System.out.println("请输入要新增的书的价格:");
        int price = scanner.nextInt();
        scanner.nextLine();
        System.out.println("请输入要新增的书的类型:");
        String type = scanner.nextLine();
        System.out.println("请输入要新增的书的数量:");
        int count = scanner.nextInt();

        // 判断该书是否已经存在。若已存在,只需把书的数量加上即可
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            if (bookList.getBooks()[i].getName().equals(name)) {
                System.out.println("该书已经存在了,因此增加数量即可");
                bookList.getBooks()[i].setCount(count + bookList.getBooks()[i].getCount());
                return;
            }
        }

        // 相当于 Books[4] = new Book(name, author, price, type, count);
        bookList.getBooks()[bookList.getUsedSize()] = new Book(name, author, price, type, count);
        bookList.setUsedSize(bookList.getUsedSize()+1);
        System.out.println("新增成功!");
    }
}

注意:Java中没有直接让数组空间大的方法,只能是拷贝一份比原来空间更大的数组。

借阅图书:

public class BorrowBook implements IWork{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在借阅图书...");
        System.out.println("请输入您要借阅的书名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            if (bookList.getBooks()[i].getName().equals(name)) {
                bookList.getBooks()[i].setLentCount(bookList.getBooks()[i].getLentCount()+1);
                System.out.println("书籍已自动发放到您的账户中,请注意查收!");
                return;
            }
        }
        System.out.println("对不起!暂时没有您要找的书,书库会尽快更新哦~");
    }
}

借阅图书就是把书架上的书的属性修改一下即可。

删除图书: 

public class DelBook implements IWork{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在删除图书...");
        System.out.println("请输入您要删除的书名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        // 注意这里查找与删除的范围
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            if (bookList.getBooks()[i].getName().equals(name)) {
                for (int j = i; j < bookList.getUsedSize()-1 ; j++) {
                    bookList.getBooks()[j] = bookList.getBooks()[j+1];
                }
                bookList.setUsedSize(bookList.getUsedSize()-1);
                System.out.println("删除成功!");
                return;
            }
        }
        System.out.println("对不起!没有您要删除的书");
    }
}

删除图书本质就是让有效的长度变小,并且让后面的元素覆盖前面的元素。

退出系统: 

public class Exit implements IWork{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在退出图书管理系统...");
        System.exit(0);
    }
}

JavaAPI中提供了一个方法可以直接强制停止程序(正常停止),就是System.exit(0),参数一定要是0才行。这会立即终止当前Java虚拟机,其中的参数0表示正常退出状态。但请注意,除非确实需要立即终止整个JVM(比如在命令行应用中),否则通常建议让程序自然执行到结束而不是使用上面的方法,以允许JVM进行清理工作。

查找图书: 

public class FindBook implements IWork {
    @Override
    public void work(BookList bookList) {
        System.out.println("正在查找图书...");
        System.out.println("请输入您要查找的书名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            if (bookList.getBooks()[i].getName().equals(name)) {
                System.out.println("下面是您要查找的书籍的相关信息:");
                System.out.println(bookList.getBooks()[i]);
                return;
            }
        }
        System.out.println("对不起!暂时没有您要找的书,书库会尽快更新哦~");
    }
}

查找图书就是遍历整个数组即可。

归还图书: 

 

public class ReturnBook implements IWork{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在归还图书...");
        System.out.println("请输入您要归还的书名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            if (bookList.getBooks()[i].getName().equals(name)) {
                bookList.getBooks()[i].setLentCount(bookList.getUsedSize()-1);
                System.out.println("归还成功!欢迎再次借书~");
                return;
            }
        }
        System.out.println("对不起!暂时没有您要归还的书~");
    }
}

显示图书:

public class ShowBook implements IWork {
    @Override
    public void work(BookList bookList) {
        System.out.println("正在显示图书...");
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            System.out.println(bookList.getBooks()[i]);
        }
    }
}

这里的显示图书,是显示所有图书,如果要显示单本图书,就是用查找图书的方法。

以上就是图书系统的基本功能啦!

这个图书系统是基于顺序表来实现的,如果有不懂的话,可以去看看那篇顺序表的博客(文章最前面)。

由于文件太多,不好全部把这些代码全部拷贝过来。

注意:上面的代码直接拷贝到编译器会报错的,因为没有导包,基本框架和IWork都是单独在包中的,Main方法是在源文件中单独存在的,并没有放入包中。

好啦!注意事项也讲完了,图书管理系统也基本实现啦!本期文章就到此结束啦!我们下一期再一起学习吧!

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

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

相关文章

web及网络基础图文详解

目录 1.1TCP/IP 协议族 1.2TCP/IP 的分层管理 1.3TCP/IP通信传输流 1.4 与 HTTP 关系密切的协议 : IP、TCP 和 DNS &#xff08;1&#xff09;负责传输的 IP协议&#xff08;网络层&#xff09; &#xff08;2&#xff09;确保可靠的 TCP协议&#xff08;传输层&#xff…

sklearn实现线性回归

sklearn实现线性回归 一、数据集介绍二、使用sklearn实现线性回归一、数据集介绍 本案例使用女性身高体重数据集,数据集如下图所示: 可以看到,数据集有15行2列。 二、使用sklearn实现线性回归 sklearn中的线性模型模块是linear_model。这里使用linear_model下的普通线性…

TiDB学习4:Placement Driver

目录 1. PD架构 2. 路由功能 2. TSO 2.1 TSO 概念 2.2 TSO分配过程 2.3 TSO时间窗口 3. 调度 3.1 信息收集 3.2 生成调度(operator) 3.3 执行调度 4. Label 与高可用 4.1 Label 的配置 5. 小结 1. PD架构 PD是整个TiDB的总控&#xff0c;相当于集群的大脑 PD集成了…

易备数据备份软件: 快速备份 MySQL\SQL Server\Oracle\泛微 OA 数据库

易备数据备份软件支持对 SQL Server、Oracle、MySQL、PostgreSQL、MariaDB、泛微 OA 等数据库进行快速备份&#xff0c;备份过程不会对任何服务造成中断。 使用一份授权&#xff0c;可以备份无限量的数据库&#xff0c;不管数据库服务器是否在本机、本地网络、或是远程网络。可…

用LabVIEW进行CAN通信开发流程

本文详细介绍了在LabVIEW中开发CAN&#xff08;Controller Area Network&#xff09;通信的流程&#xff0c;包括硬件配置、软件编程和调试步骤。重点讨论了开发过程中需要注意的问题&#xff0c;如节点配置、数据帧格式和错误处理等&#xff0c;为开发高效可靠的CAN通信应用提…

可以在搜索结果中屏蔽指定网站的插件

可以在搜索结果中屏蔽指定网站的插件 | LogDict背景 在搜索引擎中搜索问题, 往往充斥各种无效内容 比如搜个技术类的问题, 前几页CSDN, 百度百家号, 百度经验, 百度知道, 腾讯云各类云爬的水文 CSDN基本都是复制粘贴的, 甚至格式都乱码了, 虽然我以前也干过 要复制粘贴无所谓, …

Java语法篇-易错

文章目录 类型转换switch case类之间关系及UMLtry catch finally 类型转换 隐式类型转换&#xff0c;不同数值类型参与计算时&#xff0c;低精度会转化为高精度参与运算 byte,short,char参与整数运算时会转成int float,int 参与浮点数运算时会转成double 强制类型转换 高精…

Hadoop概览以及编译hadoop说明

一、Hadoop概述 Hadoop 是一个用于跨计算机集群存储和处理大型数据集的软件框架。它旨在处理大数据&#xff0c;即传统数据库无法有效管理的极其庞大和复杂的数据集。Hadoop不是传统意义上的数据仓库&#xff0c;因为它们的用途不同&#xff0c;架构也不同。Hadoop 是一个跨分布…

基于SpringBoot+Vue+Mysql的实验室低值易耗品管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

OS复习笔记ch6-2

死锁的解决 死锁的预防&#xff08;打疫苗&#xff09;死锁的避免&#xff08;戴口罩&#xff09;死锁的检测&#xff08;做核酸&#xff09; 死锁的预防 前面我们提到了死锁的四个必要条件 防止前三个必要条件&#xff0c;就是间接预防防止最后一个必要条件–循环等待&…

每日一题23:统计文本中单词出现的次数

一、每日一题 解答&#xff1a; import pandas as pd def count_occurrences(files: pd.DataFrame) -> pd.DataFrame:bull_cnt len(files[files[content].str.contains(r\sbull\s)])bear_cnt len(files[files[content].str.contains(r\sbear\s)])res_df pd.DataFrame({…

【Text2SQL 论文】SeaD:使用 Schema-aware 去噪训练的 end2end 的 Text2SQL

论文&#xff1a;SeaD: End-to-end Text-to-SQL Generation with Schema-aware Denoising ⭐⭐ NAACL 2022, arXiv:2105.07911 本论文提出 SeaD 模型&#xff0c;使用 schema-aware 的去噪方法来训练一个 end2end、seq2seq 的 Transformer 模型来实现 Text2SQL。 一、论文速读…

【LeetCode刷题记录】207.课程表

207 课程表 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学习课程 ai 则 必须 先学习课程 b…

第20届文博会:“特别呈现”—周瑛瑾雷米·艾融双个展,著名美术评论家,批评家彭德教授对周瑛瑾作品进行评论

周瑛瑾不是学院派艺术家&#xff0c;但在彩墨画领域的天赋超出中国八大美院的同类型画家。相比具有批判意识的当代艺术&#xff0c;他的彩墨艺术如同我们这个苦难世界的创可贴和安慰剂。当我面对他的彩墨画&#xff0c;首先是惊艳&#xff0c;随之想到屈原的离骚&#xff0c;还…

淘工厂订单导出自动化工具

目录 下载安装与运行 主要目的 其他工具的弊端 本工具的优势 视频演示 下载新版后的注意事项 支持的导出项 什么叫一单多拍 常见问题 如何实现快捷登录 导出卡住时如何操作 如何精确导出 下载安装与运行 下载、安装与运行 语雀 主要目的 导出订单信息&#xf…

【数据结构】哈希表的原理及其实现

文章目录 哈希表的概念哈希函数的设计常见的哈希函数 哈希冲突1. 闭散列代码实现 2. 开散列拉链法的优点 针对开散列哈希的扩展基于开散列拉链法封装哈希表MyHash.h 基于哈希表实现unordered_map类Myunordered_map.h 基于哈希表实现unordered_set类Myunordered_map.h 哈希表的概…

Ethercat总线学习:CAN、CANopen、EtherCAT、PDO与SDO

各种XoE CoE是什么 CoE CAN application protocol Over EtherCAT&#xff0c;是EtherCAT应用层协议的一种&#xff0c;根据CiA402协议编写&#xff0c;使用对象和对象字典的功能来实现邮箱通讯。 PDO与SDO是常用的数据传输方式&#xff0c;他们在实现高效数据传输、同步方面发…

html中被忽略的简单标签

1&#xff1a; alt的作用是在图片不能显示时的提示信息 <img src"https://img.xunfei.cn/mall/dev/ifly-mall-vip- service/business/vip/common/202404071019208761.jp" alt"提示信息" width"100px" height"100px" /> 2&#…

Vue2基础及其进阶面试(二)

vue2的生命周期 删除一些没用的 App.vue 删成这个样子就行 <template><router-view/></template><style lang"scss"></style>来到路由把没用的删除 import Vue from vue import VueRouter from vue-router import HomeView from .…

Java进阶学习笔记25——Objects类

为啥比较两个对象是否相等&#xff0c;要用Objects的equals方法&#xff0c;而不是用对象自己的equals方法来解决呢&#xff1f; Objects&#xff1a; Objects类是一个工具类&#xff0c;提供了很多操作对象的静态方法供我们使用。 package cn.ensource.d14_objects;import ja…