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 方法。


相关文章
|
3月前
|
JavaScript Java 测试技术
基于Java的图书馆管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的图书馆管理系统的设计与实现(源码+lw+部署文档+讲解等)
53 1
|
3月前
|
Java 数据库 Android开发
图书销售系统【纯控制台】(Java课设)
图书销售系统【纯控制台】(Java课设)
38 1
|
3月前
|
存储 Java 关系型数据库
图书馆管理系统【GUI/Swing+MySQL】(Java课设)
图书馆管理系统【GUI/Swing+MySQL】(Java课设)
32 0
图书馆管理系统【GUI/Swing+MySQL】(Java课设)
|
2月前
|
存储 小程序 Java
基于Java图书馆管理系统详细设计和实现(源码+LW+调试文档+讲解等)
基于Java图书馆管理系统详细设计和实现(源码+LW+调试文档+讲解等)
|
2月前
|
搜索推荐 算法 小程序
基于Java协同过滤算法的图书推荐系统设计和实现(源码+LW+调试文档+讲解等)
基于Java协同过滤算法的图书推荐系统设计和实现(源码+LW+调试文档+讲解等)
|
5天前
|
Java
`<jsp:getProperty>`动作和`<jsp:setProperty>`动作的使用在一个静态页面填写图书的基本信息,页面信息提交给其他页面,并且在其页面显示。要去将表单元素的值赋值给Java
该博客文章讲解了JSP中`<jsp:getProperty>`和`<jsp:setProperty>`动作的使用方法,包括它们的语法格式和如何在页面中使用这些动作来获取和设置JavaBean对象的属性值,并通过图书信息的填写和展示示例进行了演示。
`<jsp:getProperty>`动作和`<jsp:setProperty>`动作的使用在一个静态页面填写图书的基本信息,页面信息提交给其他页面,并且在其页面显示。要去将表单元素的值赋值给Java
|
8天前
|
SQL Java 数据库连接
【Java】Java Swing 图书管借阅管理系统(源码+论文)【独一无二】
【Java】Java Swing 图书管借阅管理系统(源码+论文)【独一无二】
|
2月前
|
IDE Oracle Java
Java 是一种跨平台的编程语言,可以在各种操作系统上运行。
Java 是一种跨平台的编程语言,可以在各种操作系统上运行。
|
3月前
|
安全 Java 程序员
深入理解Java并发编程:从基础到高级深入理解操作系统中的进程调度策略
【5月更文挑战第29天】 Java并发编程是Java开发中不可忽视的一部分,它涉及到多线程、同步、锁等概念。本文将带你从Java并发编程的基础概念出发,逐步深入到高级应用,让你全面掌握Java并发编程的技巧。
|
2月前
|
搜索推荐 前端开发 JavaScript
计算机Java项目|图书个性化推荐系统的设计与实现
计算机Java项目|图书个性化推荐系统的设计与实现