【Java 基础语法】纯 Java《图书管理系统》练习

前言:

之前介绍了很多 Java 语法的基础知识,但此时我感觉到有些知识学了但还是没学透。所以自己写了个图书管理系统,并且写下这篇文章,让自己对于 Java 语法的理解的更加透彻!

在这里插入图片描述

1. 构思

首先我们在敲之前要想好整体的框架,一个图书管理系统应该有什么呢?此时我们可以假想去图书馆借书

  • 用户: 就是我们要和这些书有接触的人(包括借书的人图书馆的管理员),可以构造一个 User 类去构建这个用户的共性,再通过普通用户和管理员对这个 User 类继承,并完善各自的特性
  • 书: 即我们要接触的对象
    • 每本书: 对于所有的书我们可以寻找共性(书的名字、作者、价格、类型)去构造一个 Book 类
    • 存放书的书架: 假如所有的书都在书架上,那么我们查、借、还、增、删等操作都是要借助书架来完成,这就好比一个数组,我们将这些书存入进去,那么对所有书的操作就只需要对这个书架进行就行。因此我们可以构造一个书的顺序表 BookList,然后添加一系列操作,去完成对书的各种功能

此时我们就有了用户、书、书架,而它们之间的联系就是

用户通过对书架进行操作然后去影响的状态

而对于书架的操作我们其实就可以抽象的看成下面这样的函数

public void work(BookList bookList);

而这个函数就是各种操作的一个抽象,故我们可以将对书架的操作抽象出来,写一个接口 Ioperation,再将各种功能继承这个接口,那么我们对书架进行操作时,只需要使用 work 方法,就可以实现不同的操作

2. 整体框架

接下来我们先用做一个框架图,以便于我们在敲代码时,可以依照这个框架去完善各部分在这里插入图片描述

扫描二维码关注公众号,回复: 13170966 查看本文章

那么接下来我们就根据构思先将基本的框架搭好

3. 解析各包代码

首先我根据框架图,先新建了三个包

  • 用户(user 包)
  • 书(book 包)
  • 操作(operation 包)

在这里插入图片描述

2.1 书(book 包)

这个包里面就是和书有关的内容,包括 Book 类和 BookList

2.2.1 单独的书(Book 类)

构建这个类我们先将我们自己抽取的共性想出来,我自己是使用了下面这几个属性

书名、作者、价格、类型、是否借出

接下来就之间上代码吧,因为这个比较简单

public class Book {
    
    
    private String name;
    private String author;
    private int price;
    private String type;
    private boolean isLent;

    public String getName() {
    
    
        return name;
    }
    
    public boolean isLent() {
    
    
        return isLent;
    }

    public void setLent(boolean lent) {
    
    
        isLent = lent;
    }

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

    public Book(String name, String author, int price, String type) {
    
    
        this.name = name;
        this.author = author;
        this.price = price;
        this.type = type;
    }
}

由于我定义的几个成员变量都是私有的,所以下面创建了一些成员的 getter 和 setter 方法(有些没用到的 getter 和 setter 方法我个人删除了,因为本次没有用到)

并且重写了 toString 方法,因为我们在显示书籍信息的时候会更舒服

最后再写了个构造方法,因为新增书籍时肯定要将书的各种信息都存入

2.2.2 书架(BookList)

书架我个人就设计成了顺序表,那么我们要用到哪些成员和方法呢?

  • 已存入书的数量
  • 书的数组:用来存放书
  • 一些方法

先看我的代码吧

public class BookList {
    
    
    private int usedSize=3;
    private  Book[] books =new Book[10];
    public  BookList(){
    
    
        this.books[0]=new Book("Java 核心技术卷I","Cay S.Horstmann",119,"很贵很贵的书");
        this.books[1]=new Book("鸟哥的 Linux 私房菜","鸟哥",118,"很贵很贵的书");
        this.books[2]=new Book("剑指 Offer","何海涛",65,"很贵的书");
    }
    public int getSize(){
    
    
        return usedSize;
    }
    public void setSize(int size){
    
    
        this.usedSize=size;
    }
    public void setBooks(int pos, Book book){
    
    
        books[pos]=book;
    }
    public Book getBook(int pos){
    
    
        return books[pos];
    }
}

上述代码中,个人就先存放了三本书,故 usedSize 为3,而整体设计最多可以放10本书,这其实可以根据不同的情况进行修改

后面便是一些方法,包含

  • 得到存入书的数量:寻找某本书时遍历要用到
  • 修改存入书的数量:增加和删除书籍时要用到
  • 得到某本书:取书时要用到
  • 修改某本书:新增书籍时要将新的书的信息录入

2.2 对于书架的操作(operation 包)

该包类即我们用户进行的操作,我个人设计了下面几个操作

新增、删除、查找、借阅、归还、显示所有书籍、退出系统

由于对于书架的操作我们其实就可以抽象的看成下面这样的函数

public void work(BookList bookList);

所以我们先看下接口的代码

2.2.1 操作接口

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

这里其实就用到了接口和抽象类

接着我们再通过各种操作去继承接口,并完善各自的内容

2.2.2 新增书籍

public class AddOperation implements IOperation{
    
    

    @Override
    public void work(BookList bookList) {
    
    
        if(bookList.getSize()==10){
    
    
            System.out.println("书库已满,无法增加书籍");
            return;
        }
        Scanner reader = new Scanner(System.in);
        String name;
        String author;
        int price;
        String type;
        System.out.print("请输入你要新增的书名:");
        name=reader.nextLine();
        System.out.print("请输入该书的作者:");
        author=reader.nextLine();
        System.out.print("请输入该书的价格:");
        price=reader.nextInt();
        reader.nextLine();
        System.out.print("请输入该书的类型:");
        type=reader.nextLine();

        int pos=bookList.getSize();
        Book book = new Book(name, author, price, type);
        bookList.setBooks(pos, book);
        bookList.setSize(bookList.getSize()+1);
    }
}

2.2.3 删除书籍

public class DelOperation implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        if(bookList.getSize()==0){
    
    
            System.out.println("书库无书,无法进行删除操作");
            return;
        }
        Scanner reader = new Scanner(System.in);
        String name;
        System.out.print("请输入你要删除的书名:");
        name=reader.nextLine();
        for(int i=0;i<bookList.getSize();i++){
    
    
            if(name.equals(bookList.getBook(i).getName())){
    
    
                while(bookList.getSize()-i-1!=0){
    
    
                    bookList.setBooks(i,bookList.getBook(i+1));
                    i++;
                }
                bookList.setSize(bookList.getSize()-1);
                return;
            }
        }
        System.out.println("书库无该图书,无法进行删除操作");
    }
}

2.2.4 查找书籍

public class FindOperation implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        if(bookList.getSize()==0){
    
    
            System.out.println("书库无书");
            return;
        }
        Scanner reader = new Scanner(System.in);
        String name;
        System.out.print("请输入你要查找的书名:");
        name=reader.nextLine();
        for(int i=0;i<bookList.getSize();i++){
    
    
            if(name.equals(bookList.getBook(i).getName())){
    
    
                System.out.println("已查询找到该书,信息如下:");
                System.out.println(bookList.getBook(i));
                return;
            }
        }
        System.out.println("未查询到该书");
    }
}

2.2.5 借阅书籍

public class LendOperation implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        if(bookList.getSize()==0){
    
    
            System.out.println("书库无书,无法进行借阅");
            return;
        }
        Scanner reader = new Scanner(System.in);
        String name;
        System.out.print("请输入你要借阅的书名:");
        name=reader.nextLine();
        for(int i=0;i<bookList.getSize();i++){
    
    
            if(name.equals(bookList.getBook(i).getName())){
    
    
                if(bookList.getBook(i).isLent()==false) {
    
    
                    bookList.getBook(i).setLent(true);
                    System.out.println("借阅成功");
                }else{
    
    
                    System.out.println("该书已被他人借阅,借阅失败");
                }
                return;
            }
        }
        System.out.println("未查询到该书,借阅失败");
    }
}

2.2.6 归还书籍

public class ReturnOperation implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        Scanner reader = new Scanner(System.in);
        String name;
        System.out.print("请输入你要归还的书名:");
        name=reader.nextLine();
        for (int i =0;i<bookList.getSize();i++){
    
    
            if(name.equals(bookList.getBook(i).getName())){
    
    
                if(bookList.getBook(i).isLent()==true){
    
    
                    bookList.getBook(i).setLent(false);
                    System.out.println("该书归还成功");
                    return;
                }else{
    
    
                    System.out.println("该书未被借阅,操作错误");
                    return;
                }
            }
        }
        System.out.println("未查询到你要归还的书籍,操作错误");
    }
}

2.2.7 显示所有书籍信息

public class DisplayOperation implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        if(bookList.getSize()==0){
    
    
            System.out.println("书库无书");
        }
        for(int i=0;i<bookList.getSize();i++){
    
    
            System.out.println(bookList.getBook(i));
        }
    }
}

2.2.8 退出系统

public class ExitOperation implements IOperation{
    
    
    @Override
    public void work(BookList bookList) {
    
    
        System.out.println("图书管理系统已退出,欢迎下次使用!");
        System.exit(0);
    }
}

上述具体操作其实就是你对一个顺序表进行一系列操作,当你去思考敲它们时,会发现是整个工程比较简单的一环

2.3 用户(user 包)

这个包里即我要构造的用户(管理员和普通用户),因此我先创建了父类 User。那么一个用户的基本信息有什么呢?

  • 用户名
  • 菜单:我们假想当我们去 ATM 机取钱时,我们可以看到一个界面
  • 用户要进行的操作

那么我们先看我的代码吧!

2.3.1 User 类

abstract public class User {
    
    
    protected String name;
    protected IOperation[] iOperations;

    public User(String name) {
    
    
        this.name = name;
    }

    abstract public int menu();

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

此时你会发现除了用户名的定义,其他属性和行为都有点细节问题需要思考

  • 菜单:因为普通用户和管理员的菜单是不同的,而我们不需要父类去实现具体的代码,所以我修改成了抽象类

  • 用户要进行的操作:其实整合框架的时候才很容易理解上述代码中的

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

    因为我们是需要用户去进行这些操作,而我个人针对普通用户和管理员设计成的界面其实如下图在这里插入图片描述

    所以我先创建了一个操作的数组,注意此时我没有创建对象,因为普通用户和管理员的对象(即操作)是不同的,看上述菜单就知道。之后构造了一个方法(即用户用来调用操作的),将对应操作的序号,以及要操作的对象传进去,就可以实现这些操作的使用

那么现在对于管理员和普通用户的定义也很简单了,即要将菜单和操作数组的对象进行修改

2.3.2 AdminUser 类

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("========= 管理员菜单 =========");
        System.out.println("1:查找图书");
        System.out.println("2:新增图书");
        System.out.println("3:删除图书");
        System.out.println("4:显示所有图书");
        System.out.println("0:退出系统");
        System.out.print("请输入您要执行的操作序号:");
        Scanner reader = new Scanner(System.in);
        int index = reader.nextInt();
        return index;
    }
}

2.3.3 NormalUser 类

public class NormalUser extends User{
    
    
    public NormalUser(String name){
    
    
        super(name);
        this.iOperations = new IOperation[]{
    
    new ExitOperation(), new FindOperation(), new LendOperation(), 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.print("请输入您要执行的操作序号:");
        Scanner reader = new Scanner(System.in);
        int index = reader.nextInt();
        return index;
    }
}

4. 整合代码(含主类代码)

其实我个人在写代码时肯定不可能各各细节都一步到位,肯定是在大框架下边写边改。

而既然有了上述各包的代码,我们最终主类中怎么将他们整合呢?先直接上代码

public class Main {
    
    
    public static User login(){
    
    
        System.out.println("========= 图书管理系统 =========");
        System.out.print("请输入您的姓名:");
        Scanner reader = new Scanner(System.in);
        String name = reader.nextLine();
        System.out.println("欢迎 " + name + " 登录系统");
        System.out.println("请问您是管理员(0),还是普通用户(1):");
        int choice = reader.nextInt();
        if(choice==0){
    
    
            return new AdminUser(name);
        }else{
    
    
            return new NormalUser(name);
        }
    }
    public static void main(String[] args) {
    
    
        BookList bookList = new BookList();
        User user = login();
        while(true){
    
    
            int choice=user.menu();
            user.doOperation(choice, bookList);
        }
    }
}

我们先看主方法,书架是涵盖这个图书系统所有书的一个仓库,所以我们肯定要先构造出来。

假设我们去银行取钱,那么这个书架就相当于我们这先建了一个银行。那么我们来到 ATM 机前,紧接着就是插卡登录嘛,所以我们图书管理系统也一样,我们要搞一个登录的样式,即我创建了一个 login 方法。代码很容易看懂,该方法的的返回值就是用户(这里用到了多态、动态绑定的思想)

而登录之后就会出现一个用户的菜单界面,也就是上述代码的 menu,也是这我们就可以理解,为什么用户菜单中的代码最后要我们输入执行的操作序号,以及返回值是 int 的疑惑。

最后我们再根据得到的操作序号去执行对应都操作!

5. 总结

看到这里为止,我相信你已经对图书馆里系统有了大概的了解,如果你还有疑惑的话,其实就是一顿手打代码的事。在我写这个管理系统之前我也觉得好像有点难度,但当你构思好框架之后,其实你的基石就铺的差不多了,剩下的代码一个小时,应该搞得定吧!

对我个人来说,起码之前学到的知识好像更踏实了点。并且这个图书管理系统会随着我知识的扩充,也将会有更高阶的版本等待发布,大家可以期待一下哦!

猜你喜欢

转载自blog.csdn.net/weixin_51367845/article/details/120480665