图书管理系统(附源码)

前言:前面一起和小伙伴们学习了较为完整的Java语法体系,那么本篇将运用这些知识连串在一起实现图书管理系统


目录

一、总体设计

二、书籍与书架

书籍(Book)

书架(Booklist)

三、对图书的相关操作

IOperations接口

ShowOperation

FindOperation

BorrowOperation

ReturnOperation

AddOperation

DeleteOperation

ExitOperation 

三、用户

用户抽象类(User)

NormalUser

AdminUser

Main( 测试 )

注册方法:

main方法:


以面向对象的思想来实现 图书管理系统。

一、总体设计

系统设计框架图

系统设计思想:

用不同的包来分装不同的类别。共创建book包、user包和operation包。

1、book包

与书相关的有书本与书架,封装共同放入book包,体现了封装的设计思想。

 2、user包

user包中用户分为普通用户类与管理员类,共同继承User抽象类,不同的子类有不同的行为现象,这里体现了多态的设计思想

 3、operation包

定义IOperation接口并创建接口数组,再定义不同的图书业务如删除图书类、借阅图书类、归还图书类等等去实现IOperation接口并重写业务方法。并用接口数组间接实例化图书业务对象,通过数组下标来调用不同的图书业务类。

结构图:


二、书籍与书架

书籍(Book)

提供书籍相关信息:

  • 书名
  • 作者
  • 价格
  • 类型
  • 借出情况

对于成员变量及成员方法,不可盲目地设计其权限性为public,对于这种情况,最好使用private进行封装。

代码如下:(代码中也有适当注释)

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 +
              //注意这里,借出情况信息不应该设置为ture or false
              //可以进行如68行修改
              '}';
   }
}

书架(Booklist)

书架用来存放书籍,书架可以被视为书籍数组,每一个元素都是一本书籍,提供:

  • 初始化书籍信息并封装
  • 记录存放数量并封装

代码如下:

package book;

public class BookList {

   private Book [] books =new Book[10];
   private int count;//实际放的书本数

    public BookList() {
      this.books[0]=new Book("三国演义","罗贯中",20,"小说");
      this.books[1]=new Book("西游记","吴承恩",30,"小说");
      this.books[2]=new Book("红楼梦","曹雪芹",30,"笑说");

      this.count=3;
    }
     //拿书
    public Book getBooks(int pos) {
        return books[pos];
    }
     //设置书的位置
    public void setBooks(int pos,Book books) {
        this.books[pos] = books;
    }
    //作用找书
    public Book[] getBooks(){
        return books;
    }

    public int getCount() {
        return count;
    }

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

}

三、对图书的相关操作

IOperations接口

ioperation接口的作用:

  • 被图书业务操作类实现
  • 创建IOperation接口数组,并用接口数组间接实例化图书业务对象,通过数组下标来调用不同的图书业务类。(User类中定义)

提供信息:

  • 定义含参 ( 书架 )的work方法
package ioperation;

import book.BookList;

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

ShowOperation

ShowOperation内容及作用:

  • 重写接口方法
  • 打印书籍信息
package ioperation;

import book.Book;
import book.BookList;

public class ShowOperation implements IOperations {
    @Override
    public void work(BookList bookList) {
        //记录书本数量
        int count= bookList.getCount();
        //遍历数组
        for (int i = 0; i < count; i++) {
            Book book =bookList.getBooks(i);
           // 这里不能直接打印booklist[i],因为 booklist是引用
            System.out.println(book);
        }
    }
}

FindOperation

FindOperation作用:

  • 在遍历书籍数组时利用equal方法核对书籍信息
package ioperation;
import book.Book;
import book.BookList;

import java.util.Scanner;

public class FindOperation implements IOperations {
    @Override
    public void work(BookList bookList) {
        System.out.println("查照图书----------");

        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入你要查找的图书书名:");
        String name=scanner.nextLine();

        int count=bookList.getCount();

        for (int i = 0; i < count; i++) {
           Book book =bookList.getBooks(i);
         if (book.getName().equals(name)){
             System.out.println("找到该图书"+book);
             return;
            }
        }
        //若找到了图书在22行return返回则运行不到这里
        System.out.println("没有找到这本书");
    }
}

BorrowOperation

BorrowOperation作用

  • 找到需要借阅的书籍更改借阅状态
package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class BorrowOperation implements IOperations {
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书---------");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要借阅的图书书名--");
        String name = scanner.nextLine();

        int count = bookList.getCount();

        for (int i = 0; i < count; i++) {
            Book book = bookList.getBooks(i);
            if (book.getName().equals(name)) {
                if (book.isBorrowed()) {
                    System.out.println("这本书已被借出!");
                    return;
                }
                //设置借阅情况
                book.setBorrowed(true);
                System.out.println("借阅成功!");
                return;
            }

        }
        System.out.println("没有你要借的这本书");
    }
}

ReturnOperation

ReturnOperation内容及作用:

  • 找到需要归还的书籍更改借阅状态
package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class ReturnOperation implements IOperations {

    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书--------");
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入你要归还的书:");
        String name= scanner.nextLine();

        int count= bookList.getCount();
        for (int i = 0; i < count; i++) {
          Book book = bookList.getBooks(i);
          if(book.getName().equals(name)){
              //检测前提当前是否被借出
              if(book.isBorrowed()){
                  System.out.println("归还成功!");
                  //设置为未借出
                  book.setBorrowed(false);
                  return;
              }
              System.out.println("没有你归还的书,归还失败!");
          }
        }
    }
}

AddOperation

AddOperation作用:

  • 新增书籍
package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;

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

        //判满
        int count=bookList.getCount();
        if(count==bookList.getBooks().length){
            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 newbook=new Book(name,author,price,type);

        for (int i = 0; i < count; i++) {
            Book book = bookList.getBooks(i);
            if (book.getName().equals(name)) {
                System.out.println("已存在该图书!");
                return;
            }
        }
            //放入新书
            bookList.setBooks(count,newbook);
            //书本数量加1
            bookList.setCount(count+1);

            System.out.println("新增图书成功!");
        }
    }

DeleteOperation

DeleteOperation相对复杂一点

删除步骤:

  • 遍历书籍数组记录要删除书本的下标
  • 后一个下标的书籍信息依次覆盖当前下标书籍信息,达到删除目的

代码如下:

package ioperation;
import book.Book;
import book.BookList;
import java.util.Scanner;

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

        int count=bookList.getCount();
        int pos = 0;
        int i = 0;
        //找到书
        for (; i < count; i++) {
            Book book = bookList.getBooks(i);
            if (book.getName().equals(name)) {
                pos = i;
                break;
            }
        }

            if(i==count){
                System.out.println("没有你要删除的书!");
                return;
            }

            for (int j = pos; j < count-1; j++) {
             //拿下标为j+1书
              Book book = bookList.getBooks(j+1);
              //放入j位置
              bookList.setBooks(j,book);
            }
            //书本数量减1
            bookList.setBooks(count-1,null);

            bookList.setCount(count-1);
        System.out.println("删除成功!");
        }
    }

ExitOperation 

ExitOperation 内容:

  • System.exit(0) 退出系统
package ioperation;
import book.BookList;

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

三、用户

用户分为普通用户类与管理员类。

User

创建User抽象类来抽取普通用户类与管理员类的共性,不同的子类有不同的行为现象,这里体现了多态的设计思想。因为User类为抽象类,其访问限定符应设置为protected。

User内容(共性的抽取)

  • 定义用户名
  • 定义接口数组
  • 定义doIoperation方法

doIoperation方法说明:

  • 传参数图书业务号码及书架
  • 通过对数组下标来访问对应业务
package use;
import book.BookList;
import ioperation.IOperations;

public abstract class User {

    protected String name;
   //定义接口数组
    public IOperations[] ioperations;

    public User(String name) {
        this.name = name;
    }
     
    //抽取共性菜单
    protected abstract int menu();

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

NormalUser

NormalUser继承User类

  • 在构造方法中初始化操作数组,并间接实例化操作业务等类的对象
  • 打印菜单并返回用户业务数字
package use;
import ioperation.*;
import java.util.Scanner;

public class NormalUser extends User{

    public NormalUser(String name) {
        super(name);
      this.ioperations=new IOperations[]{
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }

    @Override
    protected 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);
        return scanner.nextInt();

    }
}

AdminUser

AdminUserr继承User类

  • 在构造方法中初始化操作数组,并间接实例化操作业务等类的对象
  • 打印菜单并返回用户选择的图书业务数字
package use;
import ioperation.*;
import java.util.Scanner;

public class AdminUser extends User{

    public AdminUser(String name) {
        super(name);
       this.ioperations=new IOperations[]{
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DeleOperation(),
                new ShowOperation()
        };
    }

    @Override
    protected 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);
        return scanner.nextInt();
    }

}

Main( 测试 )

Main为测试类包含

注册方法:

  • 根据选择不同实例化不同用户对象并返回(在实例化的同时已经调用了该用户类的构造方法,也就是已经初始化好了用户的图书业务权限)
  • 返回类型为User,这里采用了向上转型

main方法:

  • 实例化书架
  • 调用Login方法获得用户身份(这里转型有疑惑的建议看多态性第五条转型问题)
  • 进入循环可以实现一次运行多次选择业务
  • 用choice接受用户需要办理的图书业务对应数字
  • 调用user的doIoperation方法完成图书操作
package use;
import book.BookList;
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 if (choice == 2) {
            return new NormalUser(name);
        }
        return null;
    }

    public static void main(String[] args) {
     
        BookList booklist = new BookList();

        User user = Login();

        while (true) {

            int choice = user.menu();

            user.doIoperation(choice, booklist);
        }
    }
}

写作不易,求路过的朋友们给个三连与关注。有写的不对的地方,欢迎大佬们在评论区指出错误并指导。

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

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

相关文章

java将html转成图片

java 将html转成图片 1.导入jar2.代码3.展示结果4.注意事项 最近有一个需求需要根据指定的样式生成图片&#xff0c;使用java原生技术有些麻烦&#xff0c;所以上网搜了下案例&#xff0c;最后发现最好用的还是html2image&#xff0c;这里进行简单总结下。 1.导入jar <!-- 用…

metasfresh开源ERP系统Windows开发环境配置参考

目录 概述 开发环境 配置过程 后端启动 前端启动 登陆系统 其他 概述 Compiere闭源之后衍生出了Admpiere等若干开源的产品&#xff0c;metasfresh就是其中之一&#xff0c;metasfresh截至发稿时在GitHub上已有64000多次的修改提交&#xff0c;而且仍在维护中&#xff0…

Python应用开发——30天学习Streamlit Python包进行APP的构建(12)

st.checkbox 显示复选框部件。 Function signature[source] st.checkbox(label, valueFalse, keyNone, helpNone, on_changeNone, argsNone, kwargsNone, *, disabledFalse, label_visibility"visible") Returns (bool) Whether or not the checkbox is checked. …

Sentinel解决雪崩问题

我们或多或少都对雪崩问题有点了解&#xff0c;在微服务系统中&#xff0c;各个微服务互相调用&#xff0c;关系错综复杂&#xff0c;如果其中一个微服务挂了或者处理消息的速度大幅下降&#xff0c;需要被处理的消息越积越多&#xff0c;那么影响的不仅仅是本微服务的功能&…

算法入门(上)

什么是算法&#xff1f; 算法&#xff08;Algorithm&#xff09;是解决特定问题求解步骤的描述&#xff0c;在计算机中表现为指令的有限序列&#xff0c;并且每条指令表示一个或多个操作。 给定一个问题&#xff0c;能够解决这个问题的算法是有很多种的。算式中的问题是千奇百怪…

C语言单链表的算法之插入节点

一&#xff1a;访问各个节点中的数据 &#xff08;1&#xff09;访问链表中的各个节点的有效数据&#xff0c;这个访问必须注意不能使用p、p1、p2&#xff0c;而只能使用phead &#xff08;2&#xff09;只能用头指针不能用各个节点自己的指针。因为在实际当中我们保存链表的时…

后端之路第三站(Mybatis)——XML文件操作sql

一、XML映射文件是啥 前面我们学过了在Mapper接口用注解的方式来操作sql语句 那么XML映射文件就另一种操作sql语句的方法 为什么还要有这么个玩意&#xff1f; 我简单说就是&#xff1a;如果有的sql特别复杂的话&#xff0c;比如需要【动态sql】的话&#xff0c;就得用到XM…

数据可视化期末总结

期末考试重点&#xff08;世界上最没意义的事情&#xff09; 选择 p8 数据可视化的标准&#xff1a; 实用、完整、真实、艺术、交互&#xff08;性&#xff09; p21 色彩三属性 色相、饱和度、亮度 p23 视觉通道的类型&#xff1a; 记得色调是定性 p39 散点图&#xff08;二维…

GIT-LFS使用

0.前言 目前git仓库有很多很大的文件需要管理&#xff0c;但是直接上传&#xff0c;每次clone的文件太大&#xff0c;所有准备使用git-lfs解决。 1、下载和安装 Git LFS 1.1、直接下载二进制包&#xff1a; Releases git-lfs/git-lfs GitHub 安装 Git LFS sudo rpm -ivh…

Leica Cyclone 3DR2024 一款功能强大的点云建模软件下载License获取

Leica Cyclone 3DR 2024 是一款功能强大的点云建模软件&#xff0c;使用旨在为用户提供全面的点云管理、自动化的点云分析&#xff0c;结合强大的建模&#xff0c;在一个直观友好的环境中&#xff0c;专注的完成挑战&#xff0c;提高生产力&#xff0c;轻松创建并交付专业的成果…

杨幂跨界学术圈:内容营销专家刘鑫炜带你了解核心期刊的学术奥秘

近日&#xff0c;知名艺人杨幂在权威期刊《中国广播电视学刊》上发表了一篇名为《浅谈影视剧中演员创作习惯——以电视剧<哈尔滨一九四四>为例》的学术论文&#xff0c;此举在学术界和娱乐圈均引起了广泛关注。该期刊不仅享有极高的声誉&#xff0c;还同时被北大中文核心…

Data-Driven Reinforcement Learning for Robotic Manipulation

意思是 不同的任务以及机器人都有单独的数据和模型 未来需要整合 一个大的数据集包含所有的 然后训练一个大模型 以后具体的任务只需要针对这个模型进行微调 challenge bootstrapping with large data 2 3 4 高清图补充

【C++】using namespace std 到底什么意思

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文作为 JohnKi 的学习笔记&#xff0c;引用了部分大佬的案例 &#x1f4e2;未来很长&a…

【SGX系列教程】(二)第一个 SGX 程序: HelloWorld,linux下运行

文章目录 0. SGX基础原理分析一.准备工作1.1 前提条件1.2 SGX IDE1.3 基本原理 二.程序设计2.1 目录结构2.2 源码设计2.2.1 Encalve/Enclave.edl:Enclave Description Language2.2.2 Enclave/Enclave.lds: Enclave linker script2.2.3 Enclave/Enclave.config.xml: Enclave 配置…

ctfshow-web入门-命令执行(web59-web65)

目录 1、web59 2、web60 3、web61 4、web62 5、web63 6、web64 7、web65 都是使用 highlight_file 或者 show_source 1、web59 直接用上一题的 payload&#xff1a; cshow_source(flag.php); 拿到 flag&#xff1a;ctfshow{9e058a62-f37d-425e-9696-43387b0b3629} 2、w…

MathType7.6专业数学公式编辑器!与Word、PPT等常用软件无缝对接。

MathType&#xff0c;一款专业的数学公式编辑器&#xff0c;以其强大的功能和友好的用户界面&#xff0c;在科研、教学等领域广受欢迎。它支持丰富的数学符号和公式模板&#xff0c;满足不同用户的需求。同时&#xff0c;MathType还提供了多种输出格式&#xff0c;方便与其他文…

3ds Max导出fbx贴图问题简单记录

1.前言 工作中发现3ds Max导出的fbx在其它软件&#xff08;Autodesk viewer&#xff0c;blender&#xff0c;navisworks&#xff0c;FBXReview等&#xff09;中丢失了部分贴图&#xff0c;但导出的fbx用3ds Max打开却正常显示。 fbx格式使用范围较广&#xff0c;很多常见的三…

如何用Go语言,实现基于宏系统的解释器?

目录 一、Go语言介绍二、什么是宏系统三、什么是解释器四、如何用Go语言实现一个基于宏系统的解释器&#xff1f; 一、Go语言介绍 Go语言&#xff0c;又称为Golang&#xff0c;是一种由谷歌公司开发并开源的编程语言。Go语言的设计目标是提高程序员的生产力&#xff0c;同时具…

树莓派开发之文件传输

文章目录 一、简介使用U盘传输文件使用SD卡传输文件使用Xftp 7传输文件 二、 总结 一、简介 在树莓派开发中经常会用到文件传输&#xff0c;下面介绍几种树莓派文件传输的几种方法。 使用U盘传输文件 &#xff08;1&#xff09;复制所需传输文件到U盘 &#xff08;2&#…

详细介绍MySQL的索引(上)

索引 索引概述 索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用(指向数据&#xff0c;这样就可以在这些数据结构上实现高级查找算法&#xff0c;这种数据结…