[JAVA] 图书管理系统

news2024/11/23 3:49:00

前言

1. 基本情况

2. 基本思路

3. 类的创建

  •       Book包底下类有实现

            (1)Book类 - 图书类 

            (2)BookList - 书架类 

  •       operation包底下类的实现(包含7个类,一个接口)

            (1)IOperation接口  - 功能接口     

            (2)AddOperation类 - 添加

            (3)Borrowperation类 - 借阅

            (4)DelOperation类 - 删除

            (5)DisplayOperation类 - 显示

            (6)FindOperation类 - 查找

            (7)ReturnOperation类 - 归还

            (8)ExitOperation类 - 退出系统

  •       user包底下类的实现

            (1)User类 - 用户

            (2)AdminUser类 - 管理员用户

            (3)NormalUser类 - 普通用户

  •       Main类的实现

4. 整体展示

5.源码


前言

本次就将主要使用java语言中的继承与多态,封装,接口等知识点,来综合性的设计与实现出一个简易的图书管理系统。

1. 基本情况

图书管理系统无非就两个角色, 管理员和普通用户, 他们实现的功能肯定也不一样

管理员主要分为: 查找图书, 新增图书, 删除图书, 显示图书, 退出图书

普通用户主要分为: 查找图书, 借阅图书, 归还图书, 退出系统

可以看下基本的实现框架如图:

2. 基本思路

1. 既然写的是图书管理肯定要有书, 我们就创建Book类, 包含图书名, 作者, 价格, 类别等等, 把这些      属性封装起来

2. 把这些书的属性封装起来, 存放到书架上. 所以创建一个书架BookList类, 相当存放到数组里面

3. 那接下来是不是还有我们的管理员AdminUser类和普能用户NormalUser, 进行图书的各种操作,        比如对图书的增删查改, 不同用户实现的功能也是不一样的

4. 为了实现图书的各种功能,如上图, 所以我们需要创建一个接口IOperation类来实现这些功能

5. 最后创建个Main类, 把上面的东西全部整合起来, 让他跑起来

3. 类的创建

看下所要创建的包和类

  • BooK包底下的实现

 (1)Book类 - 图书类

在这里的书的属性有书名、作者、价格、类型以及是否被借出,这里我结合了封装性,将属性设置为private权限,这样的话要提供相应的get方法和set方法,以及提供一个构造方法但不包含是否被借出的属性, 因为布尔值的默认类型就是false,我们一开始书肯定是没借出的,当借出我们自己提供方法让false改成ture就行了, 所以这里重写了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;
    }
    //提供set ,get的方法
    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) ? "已经借出":"未借出")+
                '}';
    }
}

 (2)BookList类 - 书架类

BookList是用来存放我们的图书的,  我们定义个数组用来存放图书和记录当前图书的大小的属性,同样结合了封装性,将属性设置为private权限,和给定一个构造方法, 一开始书架上肯定是先放了书的, 所以会在构造方法中就先定义几本书, 然后通过get, set给获取下标从而找到这本书和书本数目

具体代码如下:

package Book;

public class BookList {
    private Book[] book = new Book[10];//存放图书
    private int usedSize;//记录当前多少本书

    public BookList(){
        //一开始就放了三本书
        book[0] = new Book("三国演义", "罗贯中", 90,"小说");
        book[1] = new Book("西游记", "吴承恩", 90,"小说");
        book[2] = new Book("红楼梦", "曹雪芹", 90,"小说");
        usedSize = 3;
    }
   /*
   * 以下我们下标归定都是合法的
   * */
    //给定pos下标可以找到这本书
    public Book getBook(int pos) {
        return book[pos];
    }
    //给pos下标然后放一本书book
    public void setBook(int pos, Book book) {
        this.book[pos] = book;
    }
    //获取图书数量
    public int getUsedSize() {
        return usedSize;
    }
    //实时记录图书的数量
    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }

}
  •  operation包底下类的实现

(1)IOperation接口

接下来我们需要实现有新增,删除,显示,查找等等,他们都需要遵循一定的规范,而这个规范就由接口IOperation来实现,其实就相当于一个桥梁。在增删查改等操作中,他们的主要方式就是工作,即work(),故接口中提供对应的work()方法供接口的实现类,即各种操作进行重写, 这里的参数是一个BookList类型, 利用了多态,以下的功能实现都是利用了多态,代码实现如下:

package operation;

import Book.BookList;

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

(2)AddOperation类 - 新增图书

我们需要将操作类实现IOperation接口,同时为重写的方法work()提供书架类。将这本书的全部信息都输入进去,在书架类中添加进去图书,再将书架中书的数量加1, 这里要利用set, get获取相对应的方法来达到我们的一个要求,代码如下:

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();
        //new一个Book的对象把新增图书的信息给他传过去
        Book book = new Book(name, author, price, type);
        int currentSize = bookList.getUsedSize();//获取当前图书的数目
        bookList.setBook(currentSize, book);/把新增的图书给放到书架上
        bookList.setUsedSize(currentSize+1);//让当前图书的数目加1
        System.out.println("新增图书成功");

    }
}

(3)BorrowOperation类 - 借阅图书

很简单,就是从书架上面查找我们想要的书有没有,借助equals()方法来找, 有就返回true,然后借阅成功,没有就没借阅成功, 默认的还是false,代码如下:

package operation;

import Book.Book;
import Book.BookList;

import java.util.Scanner;

public class BorrowOperation implements IOperation{
    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);//获取i下标的图书
            if (book.getName().equals(name)){//来比较要借阅图书是否有
                book.setBorrowed(true);//有就把isBorrowed设置为true
                System.out.println("借阅成功!");
                return;
            }
        }
        System.out.println("没有你要借阅的图书!");
    }
}

(4)DelOperation类 - 删除图书

同样,从书架上查找是否有这本图书, 有就删除成功, 否则失败,代码如下:

package operation;

import Book.Book;
import Book.BookList;

import java.util.Scanner;

public class DelOperation implements IOperation{
    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();//获取当前图书数目
        int i =0;
        int flg = 0;//默认还没找到删除的标志
        for (i = 0; i < currentSize; i++) {//遍历数组
            Book book = bookList.getBook(i);
            if (book.getName().equals(name)) {
                flg = 1;//找到了改为1
                break;
            }
        }
        if (flg == 1){
       for (int j = i; j < currentSize-1; j++) {
            Book book = bookList.getBook(j);
            book = bookList.getBook(j+1);//从要删除的图书的下一位往前覆盖掉
            bookList.setBook(j, book);
        }
            bookList.setUsedSize(currentSize-1);//图书数目减1
            System.out.println("删除成功");
        }else {
            System.out.println("没有你要删除的图书");
        }

    }
}

(5)DisplayOperation类 - 显示图书

直接遍历打印就行了,代码如下:

package operation;

import Book.Book;
import Book.BookList;

public class DisplayOperation implements IOperation{
    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);
        }
    }
}

(6)ExitOperation类 - 查找图书

和前面的借阅图书差不多一样的思路的, 代码如下:

package operation;

import Book.Book;
import Book.BookList;

import java.util.Scanner;

public class FindOperation implements IOperation{
    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)){//查找是否有要找图书
                System.out.println("查找成功!");
                System.out.println(book);
                return;
            }
        }
        System.out.println("没有查到你要找的书");
    }
}

(7)ReturnOperation类 - 归还图书

还是和借阅图书模块一样的思路, 先查找要归还的图书, 查找到了, 就用setBorrow()设置成false就行(这里不考虑是否已借出),代码如下:

package operation;

import Book.Book;
import Book.BookList;

import java.util.Scanner;

public class ReturnOperation implements IOperation{
    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);//查找到了归还,就设置成false
                System.out.println("归还成功!");
                return;
            }
        }
    }
}

(8)ExitOperation类 - 退出系统

 直接调用exit(0)方法,  exit(0)表示正常退出,  exit()使程序立即正常终止,如果状态值为0则认为正常推出

package operation;

import Book.BookList;

public class ExitOperation implements IOperation{
    public void work(BookList bookList) {
        System.out.println("退出系统!!!");
        System.exit(0);//状态码
    }
}

user包底下类的实现

(1)User类 - 用户

首先我们的用户包含两部分:管理员和普通用户, 他们都是用户, 需要继承我们的User类, 子类中要都含有menu方法, 因为我们管理员和普通用户的操作菜单不同,因此依靠他们各自的类进行重写menu方法更加合适不同的子类的具体实现是不一样的。在的Main类中可以看到,是使用User发生多态(动态绑定)来调用不同的对象的,所以,一定会使用User来调用不同的menu方法,而父类没有这个方法,就要加上menu方法,但是这个可以没有具体的实现, 所以把这个menu方法变成了一个抽象方法就行了。这个User类,成了一个抽象类,抽象类的作用就是为了被继承的。在User类中,新增一个doOperation方法,能够将选择和具体的操作结合起来。代码如下:

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 doOperation(int choice, BookList bookList){
把IOperation接口当做是个数组,当传choice下标就会来调用对应的功能,然后调用父类work的方法,是利用了接口的多态来实现的, 就是发生了所谓的动态绑定
        this.iOperations[choice].work(bookList);
}

}

(2)AdminUser类 - 管理员用户

我们在AdminUser类中可以看出重写menu方法,同时对iOperation数组进行初始化,根据不同下标调用不同的功能

package User;

import operation.*;

import java.util.Scanner;

public class AdminUser extends User {
    public AdminUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DelOperation(),
                new DisplayOperation()
        };
    }

    public int menu() {
        System.out.println("hello " + this.name + " 欢迎来到图书小练习");
        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);
        int choice = scanner.nextInt();
        return choice;
    }
}


(3)NormalUser类 - 普通用户

代码如下:

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("hello "+this.name+" 欢迎来到图书小练习");
        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);
        int choice = scanner.nextInt();
        return choice;
    }
}

到这里我们所有的框架都已经搭建好了,只需要在Main类中的main方法进行测试即可,代码如下

  • Main类的实现

在Main类中,我们通过创建一个书架,同时写一个用户登录方法,菜单,以及doOperation方法,利用一个死循环一直进行选择操作,最后当用户选择退出系统时候会直接终止。

import Book.BookList;
import User.User;
import User.AdminUser;
import User.NormalUser;

import java.util.Scanner;

public class Main {

    public static User login() {
        System.out.println("请输入你的名字: ");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        System.out.println("请选择你的身份: 1>: 管理员, >0: 普通用户");
        int ret = scanner.nextInt();
        if (ret == 1) {//身份的选择,0或1来调用不同的身份
            return new AdminUser(str);
        } else {
            return new NormalUser(str);
        }
    }
    public static void main(String[] args) {
        BookList bookList = new BookList();//创建个书架,用来放图书
        User user = login();//用户登录
        while (true){
        int choice = user.menu();//调用菜单
        user.doOperation(choice,bookList);//通过传choice下标来选择不同的功能
    }
    }

}

(4)整体展示

(5)源码

登录 - Gitee.com

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

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

相关文章

蓝精灵协会每周社区会议|延长水晶铸造期限以及游戏重启计划

蓝精灵协会每周社区会议来啦&#xff01;我们已经把活动名称从「AMA」改为「市政会议厅」&#xff0c;因为该会议的目的是倾听社区反馈和进行讨论。当然&#xff0c;我们仍然非常欢迎你提出问题&#xff01; 本次市政会议厅涵盖四个主题&#xff1a; 延长水晶铸造时间的投票结果…

scrollIntoView的基本定义、以及Vue3、vue2中使用: 点击导航滚动到对应区域。

1. 基本定义 MDN 关于scorllIntoView的介绍 Element 接口的 scrollIntoView() 方法会滚动元素的父容器&#xff0c;使被调用 scrollIntoView() 的元素对用户可见。 scrollIntoView()scrollIntoView(alignToTop)scrollIntoView(scrollIntoViewOptions) 1. alignToTop 可选 alig…

aws Automation

In order to save money, CloudFormation terminates the resources from the template Systems Manager will handle on-premises and EC2 instance patches Caching Amazon CloudFront 是一种内容分发网络 (CDN) 服务&#xff0c;旨在获得优异性能、安全性和开发人员便利性…

A股市场上股票行情数据接口有那几种?

L2行情数据接口相比Level-1接口相比&#xff0c;L2行情市场具有数据更完整、推送速度更及时的优势&#xff0c;帮助投资者及时把握盘中主要资金流&#xff0c;做出更准确的投资决策。简而言之&#xff0c;Level-2最大的作用就是提前看到主力的大单&#xff0c;对于追逐日线跌停…

js解析jwt中的数据,将base64转为json方式,以及需要注意的地方

jwt前端解析 ​当我们做前后端分离项目时&#xff0c;需要将jwt保存在前端&#xff0c;有时候需要将jwt中的数据解析出来&#xff0c;网上有很多用第三方组件的方式&#xff0c;但是js的原生方法就也可以解决&#xff0c;虽然存在兼容等问题&#xff0c;但是修改一下也是可用的…

“新白色战场”增长公式发布丨数说故事2023低温鲜奶洞察

重点内容抢先看 低温鲜奶成为乳制品品类新的增长点&#xff0c;头部品牌纷纷入局&#xff0c;“新白色战场”厮杀逐年激烈。 数说故事发布《2023低温鲜奶品类洞察报告》&#xff0c;根据近两年社媒电商数据深度分析&#xff0c;总结出低温鲜奶品类增长公式。 产品力 口感性价…

ElasticSearch 同步MySQL数据方案汇总

叙述 在实际项目开发中&#xff0c;我们经常将Mysql作为业务数据库&#xff0c;ES作为查询数据库&#xff0c;用来实现读写分离&#xff0c;缓解Mysql数据库的查询压力&#xff0c;应对海量数据的复杂查询。这其中有一个很重要的问题&#xff0c;就是如何实现Mysql数据库和ES的…

Matlab如何隐藏坐标轴框线,但保留刻度及刻度标签

假如我们用Matlab绘制了这样一幅堆叠图&#xff1a; 看起来&#xff0c;哪哪都好&#xff0c;但就是感觉两条黑色的坐标轴框线有些碍事。 于是想&#xff0c;该怎么去掉呢&#xff1f; 网上对于这一问题比较常见的解答是&#xff0c;将坐标轴颜色设置为背景颜色&#xff1a; …

2023,没有人不想做黄牛

【潮汐商业评论/原创】 “没办法啊&#xff0c;只能退票了。”作为奶茶十几年的老粉&#xff0c;好不容易从其他粉丝手里买到票的Sarah无奈道。 “刘若英&#xff0c;12小时内退票”、“梁静茹&#xff0c;24小时内退票”…… 近日“演唱会闹退票”登上了热搜。起因是5月7日&…

nuitka打包python的PyQt5成exe可执行文件

使用nuitka打包python的PyQt5 可以打包多文件,也可以打包单文件。 使用的python版本是3.8.10 1、下载gcc 方式1:可以到网站下载,点我跳转 方式2:可以直接去网盘下载,点我跳转 提取码:8888 网盘里面也有python3.8.10的安装包,下载后直接安装即可。 下载64位 win…

CoolShell 博客备份QA问答

芝兰生于深谷&#xff0c;不以无人而不芳; 君子修身养德&#xff0c;不以穷困而改志 这是左耳朵耗子-陈皓[1]的座右铭&#xff0c;他的中文技术博客酷壳 - CoolShell[2]可能是许多技术人员的圣地&#xff0c;至少对我来说是的。 coolshell_talk 他在极客时间的专栏&#xff0c;…

深度学习--主动学习

主动学习简介 主动学习是指对需要标记的数据进行优先排序的过程&#xff0c;这样可以确定哪些数据对训练监督模型产生最大的影响。主动学习是一种学习算法可以交互式查询用户(teacher 或 oracle)&#xff0c;用真实标签标注新数据点的策略。主动学习的过程也被称为优化实验设计…

Oracle 存储过程语法

Oracle 存储过程语法 1. 创建表&#xff08;测试数据准备&#xff09; -- 创建用户表 create table TT_USER (USERID NUMBER(10),USERNAME VARCHAR2(255),PASSWORD VARCHAR2(255),SEX VARCHAR2(1) );INSERT INTO TT_USER VALUES (101, zhang, 111, 1); INSERT INTO TT…

Win11校园网不弹出登录页面怎么回事?

Win11校园网不弹出登录页面怎么回事&#xff1f;最近有用户在使用校园网的时候遇到了一些问题&#xff0c;访问登录网站的时候&#xff0c;一直无法显示登录的界面。那么遇到这个情况如何去进行解决呢&#xff1f;一起来看看以下的解决方法分享吧。 解决方法如下&#xff1a; 方…

【零基础学机器学习 2】 机器学习的实操步骤-以及在Python中实现机器学习模型

文章目录 1. 收集数据2. 准备数据3. 选择模型4. 训练模型5. 评估模型6. 参数调整7. 进行预测在Python中实现机器学习模型 机器学习是一种人工智能的分支&#xff0c;它使用算法和统计模型来让计算机系统自动地从数据中学习&#xff0c;并根据学习结果做出预测或决策。机器学习的…

智能双向嵌入式UART转CAN模块 串口 RS232 RS485 UART CAN转换器

CANUART-100TL系列智能双向UART转CAN模块具有一路TTL UART串口通道和一路CAN通道&#xff0c;实现CAN与串口 UART之间的双向数据智能转换。超小型灌封模块设计&#xff0c;方便用户集成到电路板上&#xff0c;快速通过MCU的UART口扩展CAN通道。 智能双向UART转CAN模块提供“…

Docker高级:Compose 容器编排

目录 一、Docker Compose 概述二、使用 Docker Compose三、常用命令四、编排微服务Ⅰ、搭建微服务Ⅱ、编写Dockerfile构建镜像Ⅲ、启动容器&#xff0c;测试服务Ⅳ、使用Compose编排容器 五、总结 一、Docker Compose 概述 Compose 是Docker公司推出的一个软件&#xff0c;可以…

跟着我学 AI丨AIGC,自媒体的核武器

自从 ChatGPT 火爆全网之后&#xff0c;AI 相关概念的热度就一直持续高涨不下&#xff0c;尤其是大众都在关注的 AI 的应用场景方向&#xff0c;更是疯狂。无论是 AI 圈内人还是以前对 AI 完全没有认知的人&#xff0c;都想借助 AI 挣上一笔。目前来说最受关注的 AI 应用场景&a…

阿里云数据库ClickHouse产品和技术解读

摘要&#xff1a;社区ClickHouse的单机引擎性能十分惊艳&#xff0c;但是部署运维ClickHouse集群&#xff0c;以及troubleshoot都不是很好上手。本次分享阿里云数据库ClickHouse产品能力和特性&#xff0c;包含同步MySQL库、ODPS库、本地盘及多盘性价比实例以及自建集群上云的迁…

kubernetes中Pod介绍

目录 kubernetes的作用 k8s核心资源pod Pod如何管理多个容器&#xff1f; Pod网络 k8s中容器的共享方式 Pod存储 已经学习了docker为什么还要学习Pod Pod与Docker之间的关系 Pod的优势 收集业务日志 pod工作方式 自主式&#xff08;不推荐&#xff09; yaml文件详解…