用面向对象技术实现的 简易图书管理系统详解

文章目录

  • 前言
  • 一、图书管理系统的大致构思
    • 用户视角的图书管理系统
      • 第一步
      • 第二步
      • 第三步
      • 总的来说
    • 管理者视角的图书管理系统
      • 第一步
      • 第二步
      • 第三步
      • 总的来说
    • 总结
  • 二、实现构思
    • 1.图书与存放图书的书架
      • 图书
      • 书架
    • 2.登录账号密码
    • 3.对书架上书的相关操作
      • 新增功能
      • 删除功能
      • 显示功能
      • 查找功能
      • 借阅功能
      • 归还功能
      • 退出功能
  • 三、整合图书管理系统
    • 1.衔接身份与操作功能,
      • 1.改造用户抽象类
      • 2.改装管理员代码
      • 3.改装普通用户代码
    • 2.改造实现图书管理系统的类,
  • 总结


前言

图书管理系统是对java语法篇的一个总结,也是对语法篇学习效果的一个总结

要写出图书管理系统就要应用到较难的抽象类,接口,继承等内容,
所以对大家的语法是有一定基础要求的;


发车喽!!!!

一、图书管理系统的大致构思

相信平常大家都打过游戏或者使用过一些软件;
咱们不如就从咱们日常使用软件的体验来构思一下

用户视角的图书管理系统

总的来说大概分为三个步骤

第一步

肯定是登录账号密码;
然后就可以进入软件,

第二步

可以反复的,凭我们的意愿来使用该软件用户所拥有的功能;
那么用户应该有哪些功能呢?

图书馆,那普通用户就是去借阅书籍的,
有借阅功能就一定有归还功能,

那为了方便用户应该再写一个查询功能吧
方便用户来查找有没有这本书,这本书有没有被借出
那么用户就只有三个功能

  • 借阅功能
  • 归还功能
  • 查询功能

第三步

使用完之后,退出软件;

总的来说

  • 要有一个登录的功能
  • 软件里的功能是可选择的且可以无限制的重复使用
  • 退出系统

管理者视角的图书管理系统

第一步

肯定也是要先登录账号密码,
然后进入软件

第二步

也可以反复的来使用该软件管理员所拥有的功能,
但是管理员不是凭自己的意愿来使用这些功能,
而是为了维护这个软件比如说新到了一批书,
管理员要做的就是去把这些书登录到图书管理系统;
所以管理员的功能有哪些呢?

新书到了肯定要登录到系统里,那就是新增功能

如果那本书意外丢失,损毁那这本书就没办法被借出了,
所以也要有一个删除功能;

如果有老年人不会使用这个系统,那么就会去问值班人员,
所以也要有一个查询功能;

图书馆要去新增图书时,肯定要看自己有哪些书,没有哪些书,
所以要有一个显示图书(遍历图书)的功能;

那么管理员就有四个功能

  • 新增功能
  • 删除功能
  • 查询功能
  • 显示功能

第三步

肯定也是退出软件

总的来说

  • 要有一个登录的功能
  • 有帮助管理员去维护这个图书管理系统的功能
  • 退出系统

总结

  • 要有一个登陆功能, 并且可以区分是普通用户还是管理员,
  • 要提供多个供普通用户选择的可以帮助到普通用户的功能,
    还要提供多个供管理员选择的可以帮助管理员维护系统的功能
  • 可以自由的退出系统

二、实现构思

1.图书与存放图书的书架

图书

图书与书架的对象都是书,
所以可以为两者创建一个包,在这里插入图片描述

首先存放在图书馆里的书,
会提供给用户一些属性,
方便他们快速找到自己想要的书
大致是以下属性:

  • 书名
  • 作者
  • 类型
  • 价格
  • 是否被借出
public class Book {
    private String name;
    private String author;
    private String type;
    private int price;
    private boolean isBorrowde;//是否被借出

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

因为有显示图书与查找图书的功能,
所以要重写toString方法

public String toString() {
        return "Book{" +
                "书名:'" + name + '\'' +
                ", 作者:'" + author + '\'' +
                ", 类型:'" + type + '\'' +
                ", 价格:" + price +
                ", " + ((isBorrowde == false)?" 未被借出":" 已被借出") +
                '}';
    }

这里使用了一个三木操作符,
因为boolean类型默认是false,
而新书肯定是未被借出的,
所以用false代表未被借出,
用true表示已被借出;

因为是一个系统,
所以数据不能是公开的,
所以要封装起来,
那么就要提供set与get方法

public boolean isBorrowde() {
        return isBorrowde;
    }

    public void setBorrowde(boolean borrowde) {
        isBorrowde = borrowde;
    }

    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 String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

所以Book类的全部代码就是

public class Book {
    private String name;
    private String author;
    private String type;
    private int price;
    private boolean isBorrowde;//是否被借出

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

    @Override
    public String toString() {
        return "Book{" +
                "书名:'" + name + '\'' +
                ", 作者:'" + author + '\'' +
                ", 类型:'" + type + '\'' +
                ", 价格:" + price +
                ", " + ((isBorrowde == false)?" 未被借出":" 已被借出") +
                '}';
    }

    public boolean isBorrowde() {
        return isBorrowde;
    }

    public void setBorrowde(boolean borrowde) {
        isBorrowde = borrowde;
    }

    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 String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

书架

一个书架可以存放多本书,所以就使用数组来实现存放书这个功能

public class Bookshelf {
    private static final int  size = 10;
    private Book[] books = new Book[size];
    private int usedSize = 0;//记录书架上有多少本书
}    

图书馆肯定是要有书的,所以咱们要提前存放进去一些书;
及构造方法:

public Bookshelf() {
        books[0] = new Book("三国演义","罗贯中","小说",99);
        books[1] = new Book("西游记","吴承恩","小说",99);
        books[2] = new Book("红楼梦","曹雪芹","小说",99);
        books[3] = new Book("水浒传","施耐庵","小说",99);
        this.usedSize = 4;
    }

因为有显示与查询功能,新增与删除功能所以要提供get与set方法

public Book[] getBooks() {
        return books;
    }
    public void setBooks(Book books) {
        this.books[usedSize] = books;
    }
    public int getUsedSize() {
         return usedSize;
    }
    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }
    public int getSize() {
        return size;
    }

所以书架的全部代码就是

public class Bookshelf {
    private static final int  size = 10;
    private Book[] books = new Book[size];
    private int usedSize = 0;//记录书架上有多少本书

    public Bookshelf() {
        books[0] = new Book("三国演义","罗贯中","小说",99);
        books[1] = new Book("西游记","吴承恩","小说",99);
        books[2] = new Book("红楼梦","曹雪芹","小说",99);
        books[3] = new Book("水浒传","施耐庵","小说",99);
        this.usedSize = 4;
    }

    public Book[] getBooks() {
        return books;
    }

    public void setBooks(Book books) {
        this.books[usedSize] = books;
    }

    public int getUsedSize() {
         return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }
    public int getSize() {
        return size;
    }
}

2.登录账号密码

由于咱们目前的知识储备还不足以写出账号密码的登陆系统,
所以一切从简
用面向对象技术实现的 简易图书管理系统详解_第1张图片
输入姓名,让他自己选择身份吧;
等以后知识储备够了再回来完善;

账号密码登录一次就可以了
所以咱们完全可以写成一个静态方法,
不如就写在主函数所在的类里,
这样就不用通过类名来调用了,

也就是说咱们现在要写一个静态的登录方法,
登录之后要让用户去输入1或者其他数来判断他的身份,
那么就可以创建一个存放普通用户与管理员这两个类的包
用面向对象技术实现的 简易图书管理系统详解_第2张图片

他们就只有被提供的操作不同
这是管理员视角

用面向对象技术实现的 简易图书管理系统详解_第3张图片

这是普通用户视角用面向对象技术实现的 简易图书管理系统详解_第4张图片
这个静态方法应用有哪些内容

  1. 提示用户输入姓名
  2. 写一个输入语句存进一个String类型的变量
  3. 提示用户选择身份
  4. 根据用户选择的身份来提供相应的界面

那么要如何来提供相应的界面呢?
通过if语句来识别他输入的身份
然后返回不同的内容

首先创建一个实现管理系统的类

public class Main {
    private static void login() {
        System.out.println("请输入姓名");
        Scanner scan = new Scanner(System.in);
        String name = scan.nextLine();
        System.out.println("请选择身份  1-> 管理员,0->普通用户");
        int choice = scan.nextInt();
        if(choice == 1) {
            System.out.println("管理员登陆成功");
        }
        else {
            System.out.println("普通用户登陆成功");
        }
    }

然后根据他的身份来提供不同的操作,
所以可以提供两个不同的菜单,

  • 普通用户
  • 管理员

那咱们就可以用一个抽象类来存储名字,
并提供这个菜单方法,
因为不管是普通用户还是管理员都有名字,有成员变量;
所以不能定义成接口来提供菜单方法
因为这个类就是要被继承的,所以他的成员变量可以用protected来修饰

抽象类:

public abstract class User {
    protected String name;
    public User(String name) {
        this.name = name;
    }
    public abstract int menu();
}

普通用户:

public class RegularUsers extends User{
	public RegularUsers(String name) {
        super(name);
    }
	public int menu() {
        System.out.println("*************************");
        System.out.println("欢迎 " + name + " 使用图书管理系统");
        System.out.println("     1.查找图书     ");
        System.out.println("     2.借阅图书     ");
        System.out.println("     3.归还图书     ");
        System.out.println("     0.退出系统     ");
        System.out.println("*************************");
        System.out.println("请输入要使用的操作");
        } 
}       

管理员:

public class Administrator extends User{
	public Administrator(String name) {
        super(name);
    }
	public int menu() {
        System.out.println("*************************");
        System.out.println("欢迎 " + name + " 使用图书管理系统");
        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("请输入要使用的操作");
	}
}	

至此,用户登录相关的代码基本写完,
当然后续为了配合其他内容的实现肯定还要进行修改

3.对书架上书的相关操作

这些操作都是基于书架上书的操作,
所以完全可以写一个接口

public interface Operation {
    void work(Bookshelf bookshelf);
}

因为是要对书架上的书去实现操作,
所以该方法要接收的是一个书架类型的参数;

以下是创建的一个存放操作类的包
用面向对象技术实现的 简易图书管理系统详解_第5张图片
咱们先来编写这些功能的代码,最后再实现整个系统的整合;

新增功能

上面书架提供了存放书的数组books,又提供了书架上已经有了多少本书usedSize,
那么如果要存放新书,直接存放到 books[usedSize] 这个位置就可以了;

  1. 先利用get方法分别得到整个数组与usedSize,
  2. 再将这本书存放到这个数组里
  3. 再利用set方法把这个数组存进书架上,让usedSize + 1;
public class NewPlus implements Operation {
    @Override
    public void work(Bookshelf bookshelf) {
        Book[] books = bookshelf.getBooks();
        System.out.println("新加一本书");
        System.out.println("请输入书名");
        Scanner scan = new Scanner(System.in);
        String name = scan.nextLine();
        System.out.println("请输入作者");
        String author = scan.nextLine();
        System.out.println("请输入类型");
        String type = scan.nextLine();
        System.out.println("请输入价格");
        int price = scan.nextInt();
        Book book = new Book(name,author,type,price);
        bookshelf.setBooks(book);
        bookshelf.setUsedSize(bookshelf.getUsedSize() + 1);
    }
}

到这一步要思考一个问题,
如果这个书架上本身就存放这本书,
那么我就不需要新增这本书了;
所以要让这个新增功能增加一个甄别的功能,
作者可能相同,类型可能相同,价格可能相同,
但是只有名字不可能相同;
所以要在输入书名后,
用这个书名去和书架上的所有书去判断是否相同,
然后做出相应提示

所以最中新增功能的代码就是

public class NewPlus implements Operation {
    @Override
    public void work(Bookshelf bookshelf) {
        Book[] books = bookshelf.getBooks();
        System.out.println("新加一本书");
        System.out.println("请输入书名");
        Scanner scan = new Scanner(System.in);
        String name = scan.nextLine();
        for(int i = 0;i < bookshelf.getUsedSize();i++) {
            if(books[i].getName().equals(name) == true) {
                System.out.println("这本书已经存在了,不能再新增了");
                return;
            }
        }
        System.out.println("请输入作者");
        String author = scan.nextLine();
        System.out.println("请输入类型");
        String type = scan.nextLine();
        System.out.println("请输入价格");
        int price = scan.nextInt();
        Book book = new Book(name,author,type,price);
        bookshelf.setBooks(book);
        bookshelf.setUsedSize(bookshelf.getUsedSize() + 1);
    }
}

删除功能

与新增功能一样,只有名字是不可能相同的,

  1. 操作者输入书名,
  2. 去书架找到这本书,
  3. 如果没有这本书,那就提示操作者无法进行这个操作
    如果有这本书,
删除的不是最后一本书 删除的是最后一本书
那就直接让数组后面的一本书去覆盖他,并且让usedSize - 1 ; 那就可以直接赋给最后一本书null,让他不指向任何对象,并且让usedSize - 1;

具体代码如下:

public class Delete implements Operation{
    @Override
    public void work(Bookshelf bookshelf) {
        System.out.println("请输入要删除的书的书名");
        Book[] books = bookshelf.getBooks();
        Scanner scan = new Scanner(System.in);
        String name = scan.nextLine();
        for(int i = 0;i < bookshelf.getUsedSize();i++) {
            if(books[i].getName().equals(name)) {
                System.out.println("删除成功");
                if(i == bookshelf.getSize() - 1) {
                    bookshelf.setBooks(null);
                }
                else {
                    for(;i < bookshelf.getUsedSize();i++) {
                        books[i] = books[i + 1];
                    }
                    break;
                }
            }
            else if(i == bookshelf.getUsedSize() - 1) {
                System.out.println("没有这本书");
                return;
            }
        }
        bookshelf.setUsedSize(bookshelf.getUsedSize() - 1);
    }
}

显示功能

这个功能的实现就比较简单了

  1. 得到数组
  2. 遍历数组
    代码如下:
public class DisPlay implements Operation {
    @Override
    public void work(Bookshelf bookshelf) {
        Book[] books = bookshelf.getBooks();
        for(int i = 0;i < bookshelf.getUsedSize();i++) {
            System.out.println(books[i]);
        }
    }
}

查找功能

  1. 操作者输入书名,
  2. 去整个书架搜索这本书
找到了 没找到
显示这本图书的基础信息以及借阅状态 提示操作者没找到

借阅功能

  1. 操作者输入书名.
  2. 去整个书架搜索这本书
  3. 如果没找到这本书就提醒操作者,
已被借出 未被借出
提醒操作者 提醒操作者成功借出,并将该书籍的借阅状态改为已被借出(将isBorrowde改为true)

代码如下:

public class Borrowing implements Operation {
    @Override
    public void work(Bookshelf bookshelf) {
        Book[] books = bookshelf.getBooks();
        System.out.println("请输入要借阅的书的书名");
        Scanner scan = new Scanner(System.in);
        String name = scan.nextLine();
        boolean flag = false;
        for(int i = 0;i < bookshelf.getUsedSize();i++) {
            if(name.equals(books[i].getName())) {
                System.out.println(books[i]);
                if(books[i].isBorrowde() == false) {
                    books[i].setBorrowde(true);
                    System.out.println("成功借出" + name);
                }
                else{
                    System.out.println("此书已被借出");
                }
                    break;
            }
            if(i == bookshelf.getUsedSize() - 1) {
                System.out.println("查无此讯");
            }
        }
    }
}

归还功能

  1. 让操作者输入书名
  2. 去整个书架搜索是否有这本书
没有这本书 有这本书
提醒操作者 提示操作者归还成功,并将该书籍借阅状态改为未被借出(将isBorrowde改为flase)

代码如下:

public class Return implements Operation {
    @Override
    public void work(Bookshelf bookshelf) {
        Book[] books = bookshelf.getBooks();
        System.out.println("请依次要归还的书的书名");
        Scanner scan = new Scanner(System.in);
        String name = scan.nextLine();
       for(int i = 0;i < bookshelf.getUsedSize();i++) {
           if(name.equals(books[i].getName())) {
               books[i].setBorrowde(false);
               System.out.println("成功归还" + name);
           }
           else if(i == bookshelf.getUsedSize()) {
               System.out.println("输入错误");
           }
       }
    }
}

退出功能

  1. 提示操作者退出系统,
  2. 使用exit方法,
    代码如下:
public class Exit implements Operation {
    @Override
    public void work(Bookshelf bookshelf) {
        System.out.println("退出系统");
        System.exit(0);
    }
}

三、整合图书管理系统

现在图书管理系统需要的各种功能的代码都已经写完了,
现在就需要整合了

用面向对象技术实现的 简易图书管理系统详解_第6张图片

这是普通用户视角用面向对象技术实现的 简易图书管理系统详解_第7张图片
由这两张图可以看出,
用户选择完身份,就要弹出对应的菜单,
并且还要可以通过数字去选择各种功能,
所以咱们是不是可以创建一个功能数组,将用户输入的数字对应成下标然后去实现相应的功能;
下面咱们对之前代码进行改装;

1.衔接身份与操作功能,

1.改造用户抽象类

  • 为他引入一个操作类型的数组,
    因为这些操作都是继承的Operation接口,
    所以这个数组的类型是所以操作的父类 Operation[] 就可以去存放所有的操作了;(自动向上转型)
  • 那么让用户输入完数组就去执行对应的操作也需要一个方法,
    public void doWork(int choice, Bookshelf bookshelf){}
    choice是用户输入的数字,bookshelf是要操作的对象;
    因为操作数组也在这个类,所以不需要传参

代码如下:

public abstract class User {
    protected String name;
    Operation[] operations;

    public User(String name) {
        this.name = name;
    }
    public abstract int menu();
    public void doWork(int choice, Bookshelf bookshelf){}
}

2.改装管理员代码

public class Administrator extends User{
    public Administrator(String name) {
        super(name);
        this.operations = new Operation[]{new Exit(),
                new Find(),
                new NewPlus(),
                new Delete(),
                new DisPlay(),
        };
    }
	//因为管理员要输入数字然后执行对应的操作,所以要返回一个整形
    public int menu() {
        System.out.println("*************************");
        System.out.println("欢迎 " + name + " 使用图书管理系统");
        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 scan = new Scanner(System.in);
        int choice = scan.nextInt();
        return choice;
    }
    public void doWork(int choice1, Bookshelf bookshelf) {
        operations[choice1].work(bookshelf);
    }
}    

3.改装普通用户代码

public class RegularUsers extends User{
    public RegularUsers(String name) {
        super(name);
        this.operations = new Operation[]{new Exit(),
                new Find(),
                new Borrowing(),
                new Return()
        };
    }
    //因为普通用户要输入数字然后执行对应的操作,所以要返回一个整形
    public int menu() {
        System.out.println("*************************");
        System.out.println("欢迎 " + name + " 使用图书管理系统");
        System.out.println("     1.查找图书     ");
        System.out.println("     2.借阅图书     ");
        System.out.println("     3.归还图书     ");
        System.out.println("     0.退出系统     ");
        System.out.println("*************************");
        System.out.println("请输入要使用的操作");
        Scanner scan = new Scanner(System.in);
        int choice = scan.nextInt();
        return choice;
    }
    public void doWork(int choice1, Bookshelf bookshelf) {
        operations[choice1].work(bookshelf);
    }
}

2.改造实现图书管理系统的类,

所有的功能都串联起来了,

下面就是实现图书管理系统的类的编写了
因为是要用户选择完身份就弹出对应的界面与可实现的功能
那么不如直接让这个静态方法的返回值就是这个身份
可能返回两种身份,普通用户与管理员,
所以可以直接让他向上转型成父类,

所以这个静态方法的返回值类型应该是 User

那么相应的if语句也要做出改变

public class Main {
    private static User login() {
        System.out.println("请输入姓名");
        Scanner scan = new Scanner(System.in);
        String name = scan.nextLine();
        System.out.println("请选择身份  1-> 管理员,0->普通用户");
        int choice = scan.nextInt();
        if(choice == 1) {
            //System.out.println("管理员登陆成功");
            return new Administrator(name);
        }
        else {
            //System.out.println("普通用户登陆成功");
            return new RegularUsers(name);
        }
    }

接下来就是主函数了✌️
首先,一定是要先创建一个书架;
然后让一个User类型的变量去接收login这个静态方法的返回值,
操作是可以反复执行的,所以还需要写一个while语句

public static void main(String[] args) {
        Bookshelf bookshelf = new Bookshelf();
        User user = login();
        while(true) {
            
        }
    }

已经用user去接收了身份,身份也已经衔接了操作功能,
所以只要重复的去接收user返回的整形,
并用user中的doWork方法去执行相应操作就ok了;

public static void main(String[] args) {
        Bookshelf bookshelf = new Bookshelf();
        User user = login();
        while(true) {
            int number = user.menu();
            user.doWork(number,bookshelf);
        }
    }

实现图书管理系统的类的
代码如下:

public class Main {
    private static User login() {
        System.out.println("请输入姓名");
        Scanner scan = new Scanner(System.in);
        String name = scan.nextLine();
        System.out.println("请选择身份  1-> 管理员,0->普通用户");
        int choice = scan.nextInt();
        if(choice == 1) {
            return new Administrator(name);
        }
        else {
            return new RegularUsers(name);
        }
    }
    public static void main(String[] args) {
        Bookshelf bookshelf = new Bookshelf();
        User user = login();
        while(true) {
            int number = user.menu();
            user.doWork(number,bookshelf);
        }
    }
}

至此整个图书管理系统就写完了;
仍有许多功能不够完善,
希望以后可以真正的写出一款有棱有角的我自己的软件;
加油啊各位!

总结

至此本篇文章结束,
新手上路,有任何谬误,欢迎大家评论区批评指正

路漫漫,不止修身也养性

你可能感兴趣的:(Java实现的算法,java,算法,后端)