Java实现简单图书操作系统思路讲解

简介: Java实现简单图书操作系统思路讲解

先给大家展示一下完成后图书系统的样子

接下来,主要讲解代码编写的思路,完整代码点击文字获取 图书管理小练习

1、分析图书系统设计到的各种类和类的属性

写代码之前,我们先要大致抽象出来一些该有的类和类的属性。

在具体写代码的时候还会有一些部分添加

1)首先 图书系统 肯定要有 书,而我们要想准确描述一本书,我们就要创建一个书类(Book)

包含属性

书名 name

作者 author

价格 price

类型 type

是否被借出 isBorrowed

2)有了书之后,就要有书架(用来存储书籍)。所以我们还要创建一个书架类 (BookList)

包含属性

Book[] (存储书籍,可以要用数组来存储)

3)用户分类,我们的图书操作系统分为 【普通用户】和【管理员】,所以我们要创建 AdminUser类(管理员) 和 NormalUser 类(普通用户)

注意:不同的用户,打印的菜单不同,这里先提醒一下大家

4)各种操作类,我们还要创建一些来对书架进行操作(简称 操作类)。主要的操作如下


查找图书(FindOperation 类)

新增图书(AddOperation 类)  

删除图书(DelOperation 类)

显示图书(DisplayOperation 类)

归还图书(ReturnOperation 类)

借阅图书(BorrowOperation 类)

退出书架(ExitOperation 类)

以上我们就基本把这个图书操作系统各个部分分析完了,而为了方便我们管理,我们还要对这些类进行分门别类。

也就是说,我们在编写代码时,把不同的类放在不同包下,用包来对这些类进行封装

 2、编写代码

【1】Book类

我们首先来写 Book 类,把图书的各种特性创建成员变量,这些成员变量用 private 修饰

private String name;//书名
    private String author;//作者
    private int price;//价格
    private String type;//类型
    private boolean isBorrowed;//是否被借出

用 private 修饰体现封装

    同时因为这些成员变量是被 private 修饰,在类外不能获取,所以我们要写一系列 get 和 set 方法,方面我们类外获取和修改这些变量。

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

     然后,构造 Book 实例时,为了方便给成员变量赋值,所以我们也可以写一个构造方法。为了方便显示 书 的内容,我们还要写一个 toString 方法

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

构造方法里面没有给 isBorrowed 赋值,是因为 isBorrowed 是 bollean 类型的变量,创建的初始值为 false,方便我们后续的操作。所以不用再给 isBorrowed 赋值


到这里 Book 类算是完成啦,接下来就是 BookList 类。

【2】BookList 类

  单独的书的类型创建好了,现在就来创建一个 BookList 类用来存储书籍。

这个 BookList 就相当于 书架

  我这里用数组来存储多本书,创建一个 Book数组 类型的成员变量,存储容量大小为10

private Book[] books = new Book[10];

存储书籍也能用 ArrayList、LinkList等....这里为了方便理解,我用了数组


存储 书 的书架有了,那我们如何知道这个书架里面有多少本书呢?

为了解决这个问题,再来创建一个成员变量来记录我们存储图书的数量

private int usedSize;//实时记录,当前books这个数组当中有多少本书

在书架中,我们可能要取书、存书等操作。而这些操作其实就是对 BookList 类中数组进行的操作,所以我们要在类中写一些方法来完成这些操作供外界使用。

通过下标获取书

在某位置下放书

获取 书架 中书的个数

修改 书架 中书的个数

/**
     * @param pos pos一定是合法的
     * @return
     */
    public Book getBook(int pos){
        return books[pos];
    }
    /**
     * @param pos 此时pos一定是合法的
     * @param book 是你要放的书
     */
    public void setBooks(int pos,Book book){
        books[pos] = book;
    }
   /**
     * 实时获取当前书的个数
     * @return
     */
    public int getUsedSize(){return usedSize;}
    /**
     * 实时的修改当前书架上的书的个数
     */
    public void setUsedSize(int size){
        usedSize = size;
    }

为了方便我们后面的操作,当我们构造 BookList 对象时,先生成三本书

public BookList(){
        books[0] = new Book("三国演义","罗贯中",19,"小说");
        books[1] = new Book("西游记","吴承恩",19,"小说");
        books[2] = new Book("红楼明","曹雪芹",19,"小说");
        usedSize = 3;
    }

【3】具体操作分析

     这里我把把这些操作方法类全部都放到一个 operation 包下面!


     因为这些 “方法” 都是对 BookList进行操作,那我们是不是可以创建一个接口,来统一标准的规范

0)IOperation 接口

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

接下来,我们让具体的操作来实现这个接口

       例如:添加图书 AddOperation 类

public class AddOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("添加图书");
    }
}

这里先不着急实现具体的业务逻辑,我们先把逻辑整理好


其他的操作也是类似,这里就不在赘述了

借阅图书 BorrowOperation


删除图书 DelOperation


展示图书 DisplayOperation


查找图书 FindOperation


归还图书 ReturnOperation


退出 ExitOperation

【4】用户分类

我们的用户分为两种,一种是管理员,另一种是普通用户。


虽然他们的操作不同,但是都是属于用户这一类,所以我们可以写一个父类 User,在父类中 定义属性和方法,然后让子类继承。这样子类就不必重复写哪些操作


0)父类 User

public class User {
    protected String name;//用户名
    public User(String name){
        this.name = name;
    }
    public abstract int menu();//打印菜单
    //因为管理员和普通用户的菜单内容不一样,所以在父类中 menu 方法我们可以直接写为抽象方法
}

1)子类 AdminUuser 和 NormalUser


    我们让子类 AdminUuser 和 NormalUser 继承 父类 User,这样我们就不用重复定义 name这个属性。

继承父类后,我们要提供一个构造方法来显示的帮助父类构造!!!

注意:不同用户菜单不同!

注意:不同用户菜单不同!

public class AdminUser extends User{
    public AdminUser(String name) {
        super(name);
    }
    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;
    }
}
public class NormalUser extends User{
    public NormalUser(String name) {
        super(name);
    }
    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;
    }
}

这里用户逻辑也基本实现啦,现在我们开始整合这些类

【5】开始整合(最难)

这里我们新创建一个类 Main(这个类不在上面任何包内),创建一个 main方法。接下来我们将在该方法中整合所以部分。


第一步:我们首先要准备我们的图书

BookList bookList = new BookList(); //准备图书

这里我们不用一本书一本的创建放到 bookList 中,因为在 BookList 实例化时就准备好了三本书


第二步:开始登陆


这里我创建一个 login 方法,然后在 main 中调用

public static User login(){
        System.out.println("请输入你的姓名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("请输入你的姓名:1 -》管理员,0 -》普通用户");
        int choice = scanner.nextInt();
        if(choice == 1){
            return new AdminUser(name);
        }else {
            return new NormalUser(name);
        }
    }

为什么 login 方法的返回值是 User?因为 AdminUser 类 和 NormalUser 类都是 User 的子类,不管我们选择哪个角色进行实例化,User 都能接收 【向上转型】


在 main 方法中,同样用 User接收

//登陆-> user 这个引用 引用那个对象
User user = login();

第三步:调用菜单,把具体操作跟菜单结合


因为上面我们一下选择 user 的实例化对象是管理员还是普通用户,所以我们直接调用menu 方法显示出来的菜单内容也是不一样的。


       所以我们要在 AdminUser 类 和 NormalUser 类分别定义 menu方法


AdminUser 类中 menu() 方法

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

NormalUser 类中 menu() 方法

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类中,我们选择的用户类型是用 父类 User 接收的,


所以我们需要 user对象来调用 menu()。


此时编译器就会报错,原因就是 User 类中没有定义 menu,所以我们还要在 User 类中写一下menu() 方法

public abstract int menu();

父类中的 menu方法不需要具体实现,定义为抽象类就行。


此时我们在用 user调用就不会出错了,menu() 方法会动态绑定!!!【我们选的哪个就会打印哪个的菜单】



然后我们创建一个变量来接收用户的选择

int choice = user.menu();//动态绑定

我们来看不同用户的菜单,在管理员菜单中 ‘2’ 是新增图书,而在普通用户菜单菜单中 ‘2’ 是借阅图书。

现在问题来了,我们如何才能知道用户想要执行那个 ‘2’ 操作呢?

我们是不是可以让  AdminUuser 对象和 NormalUser 对象中分别存储好各种要执行的操作就可以了。

现在我们重新回到 User类中,添加一个成员

protected IOperation[]  iOperations;//此时并没有初始化和分配大小

然后分别在 AdminUuser 和 NormalUser 各自的抽象方法中各自初始化具体的内容

a1ac08044fbe5961137e52b1067c8f79_17f502696f974804b8797d46f8296b6b.png

最后,在父类 User 中再定义一个具体调用哪个操作的方法

public void doOperation(int choice, BookList bookList){
        this.iOperations[choice].work(bookList);
    }

通过 choice 作为下标,来找到具体的执行类并执行类中的方法

为什么 doOperation 方法分别定义在  AdminUuser 和 NormalUser 中?


       因为如果定义在  AdminUuser 和 NormalUser 中,在整合时 use 对象就无法调用 doOperation 方法。


相关文章
|
23天前
|
设计模式 算法 安全
实时操作系统(RTOS)深度解析及Java实现初探
【10月更文挑战第22天】实时操作系统(RTOS,Real-Time Operating System)是一种能够在严格的时间限制内响应外部事件并处理任务的操作系统。它以其高效、高速、可靠的特点,广泛应用于工业自动化、航空航天、医疗设备、交通控制等领域。本文将深入浅出地介绍RTOS的相关概念、底层原理、作用与功能,并探讨在Java中实现实时系统的方法。
52 1
|
5月前
|
存储 小程序 Java
基于Java图书馆管理系统详细设计和实现(源码+LW+调试文档+讲解等)
基于Java图书馆管理系统详细设计和实现(源码+LW+调试文档+讲解等)
|
5月前
|
搜索推荐 算法 小程序
基于Java协同过滤算法的图书推荐系统设计和实现(源码+LW+调试文档+讲解等)
基于Java协同过滤算法的图书推荐系统设计和实现(源码+LW+调试文档+讲解等)
|
3月前
|
Java
`<jsp:getProperty>`动作和`<jsp:setProperty>`动作的使用在一个静态页面填写图书的基本信息,页面信息提交给其他页面,并且在其页面显示。要去将表单元素的值赋值给Java
该博客文章讲解了JSP中`<jsp:getProperty>`和`<jsp:setProperty>`动作的使用方法,包括它们的语法格式和如何在页面中使用这些动作来获取和设置JavaBean对象的属性值,并通过图书信息的填写和展示示例进行了演示。
`<jsp:getProperty>`动作和`<jsp:setProperty>`动作的使用在一个静态页面填写图书的基本信息,页面信息提交给其他页面,并且在其页面显示。要去将表单元素的值赋值给Java
|
3月前
|
消息中间件 算法 Java
深入浅出操作系统:进程管理的艺术掌握Java中的异常处理机制
【8月更文挑战第30天】在数字世界的舞台上,操作系统扮演着导演的角色,精心安排着每一个进程的表演。本文将揭开进程管理的神秘面纱,从进程的诞生到终结,探究它们如何在操作系统的指挥下和谐共舞。通过生动的比喻和直观的代码示例,我们将一同走进操作系统的核心,理解进程调度、同步与通信的内在机制,以及它们对计算生态的重要性。让我们跟随代码的节奏,一起感受操作系统的魅力吧!
|
3月前
|
存储 安全 Java
深入理解操作系统:从用户空间到内核空间的旅程深入浅出Java异常处理机制
【8月更文挑战第28天】在数字世界的海洋中,操作系统是承载软件与硬件沟通的巨轮。本文将揭开操作系统神秘的面纱,通过一次思维的航行,带领读者从应用程序的用户空间出发,穿越系统调用的大门,深入内核空间的心脏。我们将探索进程管理、内存分配、文件系统等核心概念,并借助代码示例,揭示操作系统背后的魔法。准备好了吗?让我们启航,去发现那些隐藏在日常计算活动背后的秘密。 【8月更文挑战第28天】在Java编程世界中,异常处理就像是我们生活中的急救包。它不仅保护程序不因意外而崩溃,还确保了代码的健壮性和可靠性。本文将通过简洁明了的语言和生动的比喻,带你了解Java异常处理的奥秘,从基本的try-catch语
|
3月前
|
SQL Java 数据库连接
【Java】Java Swing 图书管借阅管理系统(源码+论文)【独一无二】
【Java】Java Swing 图书管借阅管理系统(源码+论文)【独一无二】
138 0
|
5月前
|
IDE Oracle Java
Java 是一种跨平台的编程语言,可以在各种操作系统上运行。
Java 是一种跨平台的编程语言,可以在各种操作系统上运行。
|
6月前
|
安全 Java 程序员
深入理解Java并发编程:从基础到高级深入理解操作系统中的进程调度策略
【5月更文挑战第29天】 Java并发编程是Java开发中不可忽视的一部分,它涉及到多线程、同步、锁等概念。本文将带你从Java并发编程的基础概念出发,逐步深入到高级应用,让你全面掌握Java并发编程的技巧。
|
5月前
|
搜索推荐 前端开发 JavaScript
计算机Java项目|图书个性化推荐系统的设计与实现
计算机Java项目|图书个性化推荐系统的设计与实现