【Java】实现图书管理系统

文章目录

  • 1. 设计背景
  • 2. 需求分析
  • 3. 设计思路
  • 4. 实现
    • 4.1 book包
      • 4.1.1 Book类
      • 4.1.2 BookList类(书架)
    • 4.2 user包
      • 4.2.1 User 类
      • 4.2.2 AdminUser类(管理员用户)
      • 4.2.3 NormalUser类(普通用户)
    • 4.3 operation包
      • 4.3.1 IOPeration接口
      • 4.3.2 FindOperation类(查找图书)
      • 4.3.3 AddOperation类(新增图书)
      • 4.3.4 DelOperation类(删除图书)
      • 4.3.5 ShowOperation类(显示图书)
      • 4.3.6 ExitOperation类(退出系统)
      • 4.3.7 BorrowOperation类(借阅图书)
      • 4.3.8 ReturnOperation类(归还图书)
    • 4.4 Main类
    • 4.5 完整代码

1. 设计背景

  • 随着社会的发展和科技的进步,图书馆的规模和藏书量都在不断扩大,图书的管理和维护变得越来越复杂。传统的图书管理方式已经无法满足现代图书馆的需求,因此需要开发一种高效、便捷的图书管理系统来提高图书管理效率和读者的借阅体验。
  • 在这种背景下,我们设计了Java图书管理系统。该系统采用Java语言开发,具有跨平台、可扩展、可维护等优点,可以满足现代图书馆的管理需求。该系统分为管理员用户和普通用户,主要实现了图书的查询、新增、删除、借阅、归还等功能。
  • 此外,图书管理系统是 java 知识学习的运用,运用了到了类和对象,构造方法,方法调用,数组,继承,多态,封装,接口,抽象类等知识。通过这个图书管理系统的练习,能更好的帮助我们更好的巩固对前面学习知识。

2. 需求分析

这个图书系统在登陆页面分为管理员用户和普通用户,管理员用户和普通用户的实现页面不一样

  • 管理员用户需要实现的功能有查找图书, 新增图书,删除图书,显示图书,退出系统。
  • 普通用户需要实现的功能有查找图书, 借阅图书,归还图书 退出系统。

3. 设计思路

回顾面向对象的核心

  • 找到对象
  • 创建对象
  • 使用对象
  1. 首先我们需要找出图书馆里系统里的所有对象:
    在图书管理系统在的对象有用户(普通用户和管理员用户),其中还有存放书本的书架
  2. 普通用户和管理员用户所展示的页面有所不同,利用继承和多态实现这一思路。
  3. 我们将普通用户和管理员用户的操作单独封装起来设计成一个类,并且定义一个接口来接收方法,接口达到了统一性。

4. 实现

我们要完成图书系统,可以先搭框架,再完善细节。其中使用了三个包,book包;operation 包和 user 包。
在这里插入图片描述

4.1 book包

book包中包含Book类和BookList类(书架)

4.1.1 Book类

Book类针对书籍,定义了有关书的属性,作者、价格、名字、类别,状态(判断是否被借出),通过构造方法,获取 get 和 set 方法,重写了toString 函数。

代码实现:

package 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;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ((isBorrowed == true) ? " 已经借出" : " 未被借出") +
                //", isBorrowed=" + isBorrowed +
                '}';
    }
}

4.1.2 BookList类(书架)

这么多本书怎么放到书架上?其中数组可以组织数据,所以我们在书架类里会使用一个数组来存放书本

代码实现:

package book;

public class BookList {
    private Book[] books;
    private int usedSize;//记录当前书架上 实际存放书的数量
    private static final int DEFAULT_CAPACITY = 10;

    public BookList(){
        this.books = new Book[DEFAULT_CAPACITY];//当前书架能存放10本书
        //放好书!
        this.books[0] = new Book("三国演义","罗贯中",10,"小说");
        this.books[1] = new Book("西游记","吴承恩",23,"小说");
        this.books[2] = new Book("红楼梦","曹雪芹",28,"小说");

        this.usedSize = 3;
    }

    public int getUsedSize() {
        return usedSize;
    }

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

    public Book getBook(int pos){
        return books[pos];
    }

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

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

4.2 user包

user包中存放User类,AdminUser 类(管理员用户)和 NormalUser类(普通用户)

4.2.1 User 类

User 类是 AdminUser 类和 NormalUser类的父类,创建User为抽象类,抽象方法menu菜单和IOperation数组的初始化。

代码实现:

package user;

import book.BookList;
import operation.IOPeration;

public abstract class User {
    protected String name;

    protected IOPeration[] ioPerations;
    public User(String name) {
        this.name = name;
    }

    public abstract int menu();

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

4.2.2 AdminUser类(管理员用户)

通过继承User类,调用到IOperation功能接口以调用管理员用户所需的功能

代码实现:

package user;

import operation.*;

import java.util.Scanner;

//子类继承父类要先帮父类进行构造,父类对name进行初始化,
//子类就要提供一个构造方法,在构造方法中使用super方法对继承过来的成员name进行初始化
public class AdminUser extends User {
    public AdminUser(String name) {
        super(name);
        this.ioPerations = new IOPeration[]{
            new ExitOperation(),
            new FindOperation(),
            new AddOperation(),
            new DelOperation(),
            new ShowOperation()
        };
    }
    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("******************");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的操作:");
        int choice = scanner.nextInt();

        return choice;
    }
}

4.2.3 NormalUser类(普通用户)

通过继承User类,调用到IOperation功能接口以调用普通用户所需的功能

代码实现:

package user;

import operation.*;

import java.util.Scanner;

public class NormalUser extends User{
    public NormalUser(String name){
        super(name);
        this.ioPerations = new IOPeration[]{
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }

    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("******************");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的操作:");
        int choice = scanner.nextInt();

        return choice;
    }
}

4.3 operation包

一些操作类的方法放在operation包中

4.3.1 IOPeration接口

定义一个接口来接收方法,接口达到了统一性,利用多态进行操作,在以下的类中执行接口,并重载。

代码实现:

package operation;

import book.BookList;

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

4.3.2 FindOperation类(查找图书)

根据输入的书名来查找图书,有两种情况一种是找到了,输出图书信息,另一种则是没有找到。

代码实现:

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class FindOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("查找图书!");
        System.out.println("请输入你要查找的图书名字:");
        //输入书名
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        //遍历数组
        int currentSize = bookList.getUsedSize();//获取当前有几本书
        for (int i = 0; i <currentSize ; i++) {
            Book book = bookList.getBook(i);
            if(book.getName().equals(name)){
                System.out.println("找到了这本书,信息如下:");
                System.out.println(book);
                return;
            }
        }
        System.out.println("很抱歉,没有找到这本书!");
    }
}

4.3.3 AddOperation类(新增图书)

从键盘输入新增图书的成员信息使之变成书的对象,将新增图书默认放在当前最后一本书的后面。
这里我们需要做两个判断:1. 判断当前书架是否已经存放了这本书,如果已经有这本书了,就不需要存放;2. 还需要判断当前书架有没有满,如果书架满了也不进行存放(不考虑扩容)。如果前面这两个判断都没有出现,则将新增图书默认放在当前最后一本书的后面。

代码实现:

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class AddOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("新增图书!");

        Scanner scanner = new Scanner(System.in);
        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);

        //检查当前书架(数组)中有没有这本书
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book1 = bookList.getBook(i);
            if(book1.getName().equals(name)){
                System.out.println("当前书架中有这本书,不需要存放!");
                return;
            }
        }
        if(currentSize == bookList.getBooks().length){
            System.out.println("书架已经满了!");
        }else {
            bookList.setBooks(currentSize,book);
            bookList.setUsedSize(currentSize+1);
        }
    }
}

4.3.4 DelOperation类(删除图书)

输入书名进行删除,删除的步骤如下:

  1. 找到有没有这本书,如果没有则返回没有要删除的图书,反正进行删除。
  2. 从后往前进行覆盖
  3. 将最后一本书进行置空

代码实现:

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class DelOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书!");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要删除的图书:");
        String name = scanner.nextLine();

        int pos = -1;

        int currentSize = bookList.getUsedSize();
        int i = 0;
        for (; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            if (book.getName().equals(name)){
                pos = i;
                break;
            }
        }
        if(i == currentSize){
            System.out.println("没有你要删除的图书!");
            return;
        }
        //开始删除
        int j = pos;
        for (; j < currentSize-1; j++) {
            //[j] = [j+1]
            Book book = bookList.getBook(j+1);
            bookList.setBooks(j,book);
        }
        bookList.setBooks(j,null);
        bookList.setUsedSize(currentSize-1);
        System.out.println("删除成功!");
    }
}

4.3.5 ShowOperation类(显示图书)

我们在书架类里中使用了一个数组来存放书本,所以我们这里要显示图书就直接把数组里的每个对象打印出来就可以了。book实际上是一个对象,我们打印对象理论上会输出该对象的地址,但是现在不会了,因为我们在Book类中重写了我们的 toString 方法,会调用我们自己的 toString 方法,所以现在可以直接打印对象。

代码实现:

package operation;

import book.Book;
import book.BookList;

public class ShowOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("打印图书!");
        int currentSize = bookList.getUsedSize();//获取当前有几本书
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            System.out.println(book);
        }
    }
}

4.3.6 ExitOperation类(退出系统)

退出系统非常容易,只需要调用系统的 exit 方法,传入参数0进行退出运行。

package operation;

import book.BookList;

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

4.3.7 BorrowOperation类(借阅图书)

1.你要借阅哪本书?
2. 你借阅的书有没有?
3. 借阅的方式是什么?将isBorrowed置为 true表示借阅成功

代码实现:

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class BorrowOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书!");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你想要借阅的图书:");
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            if(book.getName().equals(name)){
                book.setBorrowed(true);
                System.out.println("借阅成功!");
                System.out.println(book);
                return;
            }
        }
        System.out.println("你借阅的图书不存在!");
    }
}

4.3.8 ReturnOperation类(归还图书)

归还的图书的操作与借阅类似,归还则将isBorrowed置为 false表示借阅成功。

代码实现:

package operation;

import book.Book;
import book.BookList;

import java.util.Scanner;

public class ReturnOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书!");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你想要归还的图书:");
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            if(book.getName().equals(name)){
                book.setBorrowed(false);
                System.out.println("归还成功!");
                System.out.println(book);
                return;
            }
        }
        System.out.println("你归还的图书不存在!");
    }
}

4.4 Main类

我们在Main类中执行操作,其中Main类主要包含Login方法,即实现用户登陆操作。

  1. 创建一个空的 BookList 对象(bookList)用于存放图书信息。
  2. 调用 Login 方法来进行用户登录操作,获取一个 User 对象(user)。这个 User 对象代表着当前登录的用户,可以执行特定的操作以管理图书列表。
  3. 用while(true)使程序可以持续进行,直到用户进行退出程序操作(chioce = 0)
import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;

import java.util.Scanner;

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. 普通用户");
        int choice = scanner.nextInt();

        if(choice == 1){
            //管理员
            return new AdminUser(name);
        }else {
            //普通用户
            return new NormalUser(name);
        }
    }
    public static void main(String[] args) {

        BookList bookList = new BookList();
        //user 指向哪个对象 就看返回值是什么?
        User user = login();//实现向上转型
        while (true){
            int choice = user.menu();

            System.out.println("choice:"+choice);

            //根据choice的选择来决定调用哪个方达?

            user.doOperstion(choice,bookList);
        }
    }
}

4.5 完整代码

Java 图书管理系统完整代码

由于本人技术有限,该图书管理系统是相对低级的版本,只完成命令行的交互没有实现数据库,待日后学习了更多知识就将该图书管理系统升级。

本章到这里就结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话请给个三连支持一下吧!
Fighting!!!✊

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

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

相关文章

docker笔记整理

Docker 安装 添加yum源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 安装docker yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin 启动docker systemctl start docker 查看docker状态 s…

指针(五)

1. sizeof 和 strlen 的对比 1.1 sizeof sizeof 计算变量所占用内存空间大小的&#xff0c;单位是字节&#xff0c;如果操作数是类型的话&#xff0c;计算的是使用类型创建的变量所占用空间的大小。 sizeof 只关注占用内存空间的大小&#xff0c;不在乎内存中存放了什么数据…

【博士每天一篇论文-算法】Continual Learning Through Synaptic Intelligence,SI算法

阅读时间&#xff1a;2023-11-23 1 介绍 年份&#xff1a;2017 作者&#xff1a;Friedemann Zenke&#xff0c;巴塞尔大学弗里德里希米歇尔研究所(FMI) Ben Poole&#xff0c;谷歌 DeepMind 研究科学家 期刊&#xff1a; International conference on machine learning. PMLR…

天线阵列车载应用——前言

本书的总体结构 这本参考书向读者介绍了汽车工业中使用的尖端天线阵列技术。新型通信多阵元天线系统是一种非常有前途的车载设备。例如&#xff0c;智能车辆公路系统(IVHS)包括车对车通信、汽车到路边系统、防撞雷达天线阵列和用于自动巡航控制应用的智能天线阵列&#xff0c;为…

数据可视化工具之选,三选一?

在数据可视化的世界中&#xff0c;选择一款合适的工具对于提升工作效率和洞察力至关重要。本文将对三款主流数据可视化工具进行详细比较&#xff0c;包括山海鲸可视化、Echarts和D3.js&#xff0c;以帮助您做出明智的选择。 山海鲸可视化 山海鲸可视化是一款免费且功能强大的…

手机如何扫描身份证?分享两个方法!

在现代社会&#xff0c;身份证已经成为我们生活中不可或缺的重要证件之一。有时候&#xff0c;我们需要将身份证信息提交给相关部门或者机构&#xff0c;而手动输入身份证信息不仅繁琐&#xff0c;还容易出错。这时&#xff0c;使用手机扫描身份证就成了一个方便快捷的选择。本…

Web性能优化之如何评估网页性能——性能指标和度量工具介绍

前言 用户在访问 web 网页时&#xff0c;大部分都希望网页能够在一秒完成。事实上&#xff0c;加载时间每多 1 秒&#xff0c;就会流失 7%的用户。如果时间超过 8s 用户就会感到不耐烦、会放弃访问。这也就是著名的 “8秒原则”。 虽然当今设备及网络环境都大幅提升&#xff…

C语言assert断言详解指针(3)

各位少年&#xff0c;大家好&#xff0c;我是博主那一脸阳光&#xff0c;今天分享assert法官的断言&#xff0c;指针宝箱的使用。 前言&#xff1a;如果你在计算机的世界中触犯了语法法规&#xff0c;那么编译器就要上线了&#xff0c;就会出现报错。然而想想我们在现实中设计到…

【Linux】Linux基本指令

目录 1.ls指令 2.cd指令 3.touch指令 4.mkdir指令 5.rmdir指令和rm指令 5.1rmdir指令 5.2rm指令 6.man指令 7.cp指令 8.mv指令 9.cat指令 10.more指令 && less指令 10.1more指令 10.2less指令 11.head指令 && tail指令 11.1head指令 11.2tai…

MySQL优化必备知识-索引篇

索引用于快速查找具有特定列值的行。如果没有索引&#xff0c;MySQL必须从第一行开始&#xff0c;然后读取整个表以查找相关行。表越大&#xff0c;成本越高。如果表中有相关列的索引&#xff0c;MySQL可以快速确定在数据文件中间查找的位置&#xff0c;而不必查看所有数据。这…

vue常用指令(v-on传递参数和事件修饰符)

1、传 递 自 定 义 参 数 : 函 数 调 用 传 参 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title…

企业的多域名SSL证书

多域名SSL证书作为一种加密通信的方式&#xff0c;可以有效保护多个网站的用户数据在传输过程中的安全。不管个人或者企事业单位 都可以申请多域名SSL证书&#xff0c;提高网站的安全性&#xff0c;保护网站数据传输安全。今天就随SSL盾了解多域名SSL证书旗下的企业多域名SSL证…

详解SpringCloud微服务技术栈:深入ElasticSearch(4)——ES集群

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;详解SpringCloud微服务技术栈&#xff1a;深入ElasticSearch&#xff08;3&#xff09;——数据同步&#xff08;酒店管理项目&a…

盛水最多的容器(Python+Go)

给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。(不能倾斜容器) 输入&#xff1a;[1,8,6,2,5…

windows设置openDNS

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十九&#xff09;——windows设置openDNS 文章目录 win系统环境搭建&#xff08;十九&#xff09;——windows设置openDNS1.什么是openDNS&#xff1f;2.openDNS的ip是多少&#xff1f;3.设置DNS3.1 设置…

linux服务器上安装mysql

今天在华为云上安装mysql&#xff0c;安装命令很简单&#xff0c;就一行命令&#xff1a;sudo apt-get update && sudo apt-get install mysql-server 我安装的是mysql8.0版本&#xff0c;这里主要说一下安装mysql后怎么在外网连接&#xff1a; 1、注释掉 bind-add…

HCIP-Datacom(H12-821)61-70题解析

有需要完整题库的同学可以私信博主&#xff0c;博主看到会回复将文件发给你&#xff01;&#xff08;麻烦各位同学给博主推文点赞关注和收藏哦&#xff09; 61、以下哪个场景不适合部署接口策略路由 A.企业网络多ISP出口的场景下&#xff0c;内网不同的网段通过不同的ISP出口访…

PHP的线程安全与非线程安全模式选哪个

曾经初学PHP的时候也很困惑对线程安全与非线程安全模式这块环境的选择&#xff0c;也未能理解其中意。近来无意中看到一个教程对线程安全&#xff08;饿汉式&#xff09;&#xff0c;非线程安全&#xff08;懒汉式&#xff09;的描述&#xff0c;虽然觉得现在已经能够很明了透彻…

设计模式_迭代器模式_Iterator

案例引入 编写程序展示一个学校院系结构: 需求是这样&#xff0c;要在一个页面中展示出学校的院系组成&#xff0c;一个学校有多个学院&#xff0c;一个学院有多个系 【传统方式】 将学院看做是学校的子类&#xff0c;系是学院的子类&#xff0c;小的组织继承大的组织 分析&…

串口通信(基于51单片机)

师从江科大 串口介绍 1、串口可以实现两个设备的相互通信。 2、单片机的串口可以使单片机与单片机&#xff0c;单片机与电脑&#xff0c;单片机与多种模块相互通信 3、单片机内部自带UART&#xff08;通用异步收发器&#xff09;&#xff0c;可实现单片机的串口通信 硬件电…