图书管理系统——Java版

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

个人主页:我要学编程(ಥ_ಥ)-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方法是在源文件中单独存在的,并没有放入包中。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaEE初阶多线程 (5)

1.锁的策略 1.1锁的策略是什么 这个锁的策略可以理解为&#xff0c;一种做法&#xff0c;相当于当你遇到锁竞争&#xff0c;加锁解锁&#xff0c;的情况你会怎么做。 乐观锁可以理解为疫情的时候比较乐观就买了最基本的物资&#xff0c; 买的时候非常方便 1.2乐观锁 当效率…

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…

2024/5/26周报

文章目录 摘要Abstract文献阅读题目创新点方法网络架构LSTM 实验过程Data acquisitionData preprocessingAlgorithm parameter settingsModels evaluation 实验结果 深度学习ARIMA一、ARIMA模型的基本思想二、ARIMA模型的数学表达式三、差分过程 总结 摘要 本周阅读了一篇基于…

Aya 23 是 Cohere For AI 推出的一款最先进的新型多语言开放重量模型

相信一些对LLM关注较高的同学们&#xff0c;应该对这家加拿大的Cohere不会太陌生。毕竟此前&#xff0c;它就开源过 Aya 101 和 Command R 这两款大模型。 Cohere 的非营利性研究实验室 Cohere for AI 发布了 Aya 23&#xff0c;这是其多语言大型语言模型 &#xff08;llm&…

计算机毕业设计 | SpringBoot社区物业管理系统 小区管理(附源码)

1&#xff0c; 概述 1.1 课题背景 近几年来&#xff0c;随着物业相关的各种信息越来越多&#xff0c;比如报修维修、缴费、车位、访客等信息&#xff0c;对物业管理方面的需求越来越高&#xff0c;我们在工作中越来越多方面需要利用网页端管理系统来进行管理&#xff0c;我们…

就业班 第三阶段(ELK) 2401--5.20 day1 ELK 企业实战 ES+head+kibana+logstash部署(最大集群)

ELKkafkafilebeat企业内部日志分析系统 1、组件介绍 1、Elasticsearch&#xff1a; 是一个基于Lucene的搜索服务器。提供搜集、分析、存储数据三大功能。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff…

力扣HOT100 - 287. 寻找重复数

解题思路&#xff1a; 快慢指针 第一步&#xff0c;慢指针每次移动一步&#xff0c;快指针每次移动两步&#xff0c;直到它们相遇。这一步保证了它们在环中相遇。 接下来&#xff0c;将其中一个指针&#xff08;快指针或慢指针&#xff09;重置到起点&#xff08;即数组的第一…

IP数据云确认参展2024 ChinaJoy BTOB与诸位共展未来!

作为在全球数字娱乐领域兼具知名度与影响力的年度盛会&#xff0c;2024年第二十一届ChinaJoy BTOB将于7月26日至7月28日在上海新国际博览中心盛大召开&#xff0c;秉承着初心“游”在&#xff0c;精彩无限&#xff01;&#xff08;英译&#xff1a;Stay True, Game On.&#xf…

数据库攻防之MySQL

MySQL 是最流行的关系型数据库&#xff0c;与此同时也是 web 应用中最好的关系型数据库管理应用软件。我们在渗透过程中碰到的 PHP 站点大部分都会搭配 MySQL 数据库&#xff0c;因此它是红队攻防中最常遇到的数据库。 0x01 MySQL简介 MySQL 是典型的关系型数据库&#xff0c;…

Gradle筑基——Gradle Maven仓库管理

基础概念&#xff1a; 1.POM pom:全名Project Object Model 项目对象模型&#xff0c;用来描述当前maven项目发布模块的基础信息 pom主要节点信息如下&#xff1a; 配置描述举例&#xff08;com.android.tools.build:gradle:4.1.1&#xff09;groupId组织 / 公司的名称com.…

Linux-之 简易:Shell编程

1 为什么要学习Shell编程 对于JavaEE和Python程序员来说,工作的需要,你的老大会要求你编写一些Shel脚本进行程序或者是服务器的维护,比如编写一个定时备份数据库的脚本. 对于大数据程序员来说,需要编写Shell程序来管理集群 2 Shell是什么 Shell是一个命令行解释器&#xff…

AIGC 005-Dreambooth定制化生成,微调文本到图像的扩散模型!

AIGC 005-Dreambooth定制化生成&#xff0c;微调文本到图像的扩散模型&#xff01; 文章目录 0 论文工作1 论文方法2 效果 0 论文工作 DreamBooth 论文 (DreamBooth: Fine-Tuning Text-to-Image Diffusion Models for Subject-Driven Generation) 提出了一种新颖的技术&#x…

AI视频教程下载:用提示工程在GPT商店构建10个GPTs

你将学到什么&#xff1f; 深入了解ChatGPT平台和GPT商店的生态系统。 开发为多样化应用定制GPT模型的专业知识。 掌握高效内容生成的AI自动化技术。 学习高级提示工程以优化ChatGPT输出。 获取构建AI驱动的数字营销和广告解决方案的技能。 了解如何为SEO写作和优化创建专…

iOS--锁的学习

iOS--锁的学习 锁的介绍线程安全 锁的分类自旋锁和互斥锁OSSpinLockos_unfair_lockpthread_mutexpthread_mutex的属性 NSLockNSRecursiveLockNSConditionNSConditionLockdispatch_semaphoredispatch_queuesynchronizedatomicpthread_rwlock&#xff1a;读写锁dispatch_barrier_…

S1E45:单链表1 课后作业

测试题&#xff1a;0. 相比起数组来说&#xff0c;单链表具有哪些优势呢&#xff1f; 答&#xff1a;长度非固定&#xff0c;可以申请添加长度 答案&#xff1a;对于数组来说&#xff0c;随机插入或者删除其中间的某一个元素&#xff0c;都是需要大量的移动操作&#xff0c;而…

Vue.Draggable:强大的Vue拖放组件技术探索

一、引言 随着前端技术的不断发展&#xff0c;拖放&#xff08;Drag-and-Drop&#xff09;功能已经成为许多Web应用不可或缺的一部分。Vue.js作为现代前端框架的佼佼者&#xff0c;为开发者提供了丰富的生态系统和强大的工具链。Vue.Draggable作为基于Sortable.js的Vue拖放组件…

在二十三届中国科学家论坛大会上,郎百忠被授予《中国首席政治书法领域科学家》荣誉称号

在5月25日于北京举办的第二十三届中国科学家论坛上&#xff0c;备受瞩目的书法家郎百忠凭借其卓越的书法造诣和深厚的政治素养&#xff0c;荣获了"中国首席政治书法科学家"称号。这一荣誉是对郎百忠多年来在书法领域的杰出贡献以及他在政治书法领域的卓越成就的肯定。…

leedcode【19】. 删除链表的倒数第 N 个结点——Java解法

Problem: 19. 删除链表的倒数第 N 个结点 思路解题方法复杂度Code性能 思路 如果要删除倒数第n个节点&#xff0c;让fast移动n步&#xff0c;然后让fast和slow同时移动&#xff0c;直到fast指向链表末尾。删掉slow所指向的节点就可以了。 分为如下几步&#xff1a; 定义fast指…

AI重塑保险业未来:机器学习在风险评估、欺诈检测与客户服务中的深度应用

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

Adobe Bridge BR v14.0.3 安装教程 (多媒体文件组织管理工具)

Adobe系列软件安装目录 一、Adobe Photoshop PS 25.6.0 安装教程 (最流行的图像设计软件) 二、Adobe Media Encoder ME v24.3.0 安装教程 (视频和音频编码渲染工具) 三、Adobe Premiere Pro v24.3.0 安装教程 (领先的视频编辑软件) 四、Adobe After Effects AE v24.3.0 安装…