综合JavaSE语法实现-----图书馆管理系统(包教包会)

本文档详细介绍了如何使用Java编程实现一个简单的图书馆管理系统。系统包括图书类、书架类、用户类和各种操作类,如添加图书、借阅、归还等。用户通过菜单选择操作,管理员和普通用户有不同的权限。整个项目综合运用了面向对象编程的多种概念和技术,如类、对象、抽象类、接口、封装、继承和多态。
摘要由CSDN通过智能技术生成

📢 文章前提:

相信大家都有去过图书馆,当我们要借阅或者归还该图书馆的图书的时候,会用到一个机器,机器上有借阅图书,归还图书,查找图书……功能

如下图:👇
在这里插入图片描述
☝️ 我们可以看到界面里包含图书名,作者名,图书的借阅情况……

📌 今天本博客将借助 Java 来实现类似这样的一个简化版图书馆管理系统


📑 文章目录:

1️⃣ 思路分析

2️⃣ 代码分析

3️⃣ 源代码
在这里插入图片描述


1️⃣ 思路分析

图书管理系统,该项目是 JavaSE 语法以及数据结构的简单综合应用,该项目用到了以下知识:👇

类,对象,抽象类,接口,封装,继承,多态,顺序表

👉 所以这个小项目可以综合复习运用到以上知识,并让我们真正的去了解面向对象编程这个概念

现在正式分析该项目的思路:

  1. 首先我们需要定义一个 book 类,这个类代表的是一本书的基本信息,包括该书的书名,作者名,价格,是否在馆,并编写构造方法,对图书的基本信息进行初始化,提供 Get Set 接口实现信息的输入输出,重写 toString 方法,便于一会打印图书的信息,该 book 类需要自己动手代码很少,除了图书基本信息的定义,其他内容都可以使用快捷键(Alt + Ins)快速生成
  2. 图书馆一般都是成千上万的图书,这时候需要我们把每一本书组织起来,这时候用到顺序表,所以第二步需要定义一个 bookList,,这里我们可以把这样的一个顺序表看作一个书架,书架用于存放组织图书
  3. 在编写操作(操作的是 bookList 顺序表)时,我们稍微的增大难度,不在 bookList 中实现对图书的操作,我们让操作也面向对象,这就意味着,每一个操作都是一个类,所以第三步就是根据不同的操作去创建不同的类
  4. 由于用户中存在普通用户以及后台管理人员,所以第四步我们需要定义一个 user 包,里面定义三个类,一个用户类(父类),一个普通用户类(子类),一个管理员类(子类),用户类作为两种具体身份类的父类,普通用户类和管理员类可以继承父类属性及方法,在子类中提供构造方法,构造方法中构造好操作类数组,然后根据不同的身份去定义菜单,由于用户需要根据菜单去进行选择实现的功能,所以菜单里面需要返回用户输入的选项,切记在父类中也要定义一个 menu 方法,方便一会进行动态绑定
  5. 提供一个 Main 类作为整个程序的入口,输入初始化信息,姓名以及管理员用户的身份信息,根据不同的身份去调用不同的类,根据不同类再去调用不同的菜单,这里会发生动态绑定和向上转型,调用菜单会返回一个操作的选项,根据此选项去实现不同的操作
  6. 每一个操作都设计成一个类,最后就是实现每一个功能的实现

📄 图解:👇
在这里插入图片描述


2️⃣ 代码分析

步骤一、先编写一个图书类(代表的是一本图书),定义图书的基本属性+构造方法+重写 toString 方法,由于图书本身的属性不需要外界的操作,所以这里使用私有属性 private 进行成员属性的修饰 👇

private String name;
    private String author;
    private int money;
    private String type;
    private boolean isBorrow;
    public Book(String name, String author, int money, String type) {
        this.name = name;
        this.author = author;
        this.money = money;
        this.type = type;
    }

    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 getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public String getType() {
        return type;
    }

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

    public boolean isBorrow() {
        return isBorrow;
    }

    public void setBorrow(boolean borrow) {
        isBorrow = borrow;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", money=" + money +
                ", type='" + type + '\'' +
                ((isBorrow == true) ? " 该书未在馆 " : " 该书在馆 ") +
                '}';
    }
}

步骤二、(拆解讲解)👇

①.定义 bookList (书架),即是定义一个顺序表,顺序表底层是一个数组,先初步搭建一个顺序表,这里默认书架上可以存放十本图书,定义一个大小为 10 的图书(Book)类的数组,再定义一个 usedSize 去记录目前书架的现有图书数量

public class BookList {
    private Book[] books = new Book[10];
    private int usedSize;

②.提供书架 bookList 的构造方法,这里先默认在书架上放了三本书,按照 Book 类的构造方法初始化三本书,再把计数器赋值成 3

public BookList() {
        books[0] =  new Book("三国演义","罗贯中",17,"小说");
        books[1] = new Book("西游记","吴承恩",47,"小说");
        books[2] = new Book("水浒传","施耐庵",37,"小说");
        usedSize = 3;
    }

③.提供计数器 usedSize 的输入输出的接口,由于图书在后面有单独的插入展示操作,所以这里不需要提供数组的输入输出接口

public int getUsedSize() {
        return usedSize;
    }

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

④.提供两个方法,分别是用来得到指定下标的图书,在指定位置插入图书,由于书架是一个顺序表(数组),所以这里可以利用下标对书架进行操作,两个操作过于简单不做展开

public Book getBook(int pos){
        if (pos < 0 || pos > usedSize){
            System.out.println("位置不合法");
            return null;
        }
        return books[pos];
    }
    public void setBook(int pos, Book book){
        if (pos < 0 || pos > usedSize){
            System.out.println("位置不合法");
            return;
        }
        this.books[pos] = book;
    }

步骤三、以上的代码都是关于图书的所以把 Book 类和 BookList 类都放在 book 包中,之后定义一个 operation 包里面,实现对图书的操作

①.先定义一个接口 IOperation,里面定义一个 Scanner 类便于其他操作类输入信息,在接口中实现减少代码重复,再定义一个 work 方法参数是bookList(书架),因为需要对书架上的书进行操作,在接口中定义 work 方法是为了方便通过多态去对实现不同的操作

public interface IOperation {
    Scanner scanner = new Scanner(System.in);
    void work(BookList bookList);
}

②.新增图书,重写 work 类实现增加图书,输入新增图书的属性,把这些属性初始化成一本书,利用上面写好的插入方法把该书插入到书架上,然后书架书的数目增加一本

public class AddOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("新增图书!");
        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();
        Book book = new Book(name,author,price,type);
        int size = bookList.getUsedSize();
        bookList.setBook(size,book);
        bookList.setUsedSize(size+1);
        System.out.println("新增图书成功!");
    }
}

③.借阅图书,输入借阅的书名,循环在书架上进行查找,找到了把 isBorrow 赋值为 true 证明该书被此人借阅出去了,循环结束时还没找到证明没有这本书

public class BorrowOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在进行借阅图书操作");
        System.out.println("输入你想要借阅的图书名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int i = 0;
        for (i = 0; i < bookList.getUsedSize(); i++) {
            Book book = bookList.getBook(i);
            if (book.getName().equals(name)){
                System.out.println("该书在馆可以借阅");
                book.setBorrow(true);
                System.out.println(book);
                break;
            }
        }
        if (i == bookList.getUsedSize()){
            System.out.println("该书没有或未在馆内无法借阅");
            return;
        }

    }
}

④.删除图书,输入想要删除的图书名,循环去进行查找如果找到了就把该书的位置 i 赋值给 pos 记录好当前图书的位置,如果循环结束没有找到就是没有这本书,最后进行删除操作,即把该书后面的数组元素都向前赋值一个位置,为了防止越界访问,删除的时候循环的终止条件是书架的图书总数减 1
最后把最后一个数组元素指向空对象并把图书的个数减少一本

public class DelOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在进行删除图书操作");
        System.out.println("输入想要进行删除操作的图书名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int pos = 0;
        int i = 0;
        for (i = 0; i < bookList.getUsedSize(); i++) {
            Book book = bookList.getBook(i);
            if (book.getName().equals(name)){
                pos = i;
            }
        }
        if (i >= bookList.getUsedSize()){
            System.out.println("没有此书");
        }
        for (int j = pos; j < bookList.getUsedSize() - 1; j++) {
            Book book = bookList.getBook(j + 1);
            bookList.setBook(j,book);
        }
        bookList.setBook(bookList.getUsedSize(), null);
        bookList.setUsedSize(bookList.getUsedSize() - 1);
        System.out.println("删除图书成功");
    }
}

⑤.展示图书,循环打印出对应下标位置的图书即可

public class DisplayOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在进行展示图书操作");
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            System.out.println(bookList.getBook(i));
        }
    }
}

⑥.退出界面,使用 System.exit(0) 退出 0 代表正常程序结束

public class ExitOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在进行退出操作");
        System.exit(0);
    }
}

⑦.查找指定名字的图书,循环和输入的图书名进行比对,找到了打印这本书的信息程序结束,循环结束证明没找到

public class FindOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("正在进行查找图书操作");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            Book book = bookList.getBook(i);
            if (book.getName().equals(name)){
                System.out.println("该书在馆");
                System.out.println(book);
                return;
            }
        }
        System.out.println("图书不存在");
    }
}

⑧.归还图书,输入归还的图书名,循环进行比对,找到了把 isBorrow 赋值为 false 证明图书在馆,循环结束没找到,证明归还的不是本图书馆的图书

public class ReturnOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书");
        System.out.println("请输入你要归还的图书的名字:");
        String name = scanner.nextLine();
        int size = bookList.getUsedSize();
        for (int i = 0; i < size; i++) {
            Book book = bookList.getBook(i);
            if(name.equals(book.getName())) {
                book.setBorrow(false);
                System.out.println("归还成功!");
                System.out.println(book);
                return;
            }
        }
        System.out.println("没有你要归还的这本书!");
    }
}

步骤四、定义一个 user 包,里面包括两种不同的身份和一个父类 User 用来存储二者共同属性

①.定义父类 User ,定义姓名,构造方法对名字进行初始化

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

②.定义一个菜单方法,两种身份的人都需要进行调用,父类的菜单方法不需要写任何内容,所以把其定义为抽象类,菜单的实现交给子类重写,方便实现动态绑定

public abstract int menu();

③.定义一个操作类数组,通过该数组可以去实现对应菜单标号的操作

protected IOperation[] iOperations;

④.提供一个实现操作的方法,通过用户/管理员的选择数字去对顺序表实现操作

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

⑤.定义一个普通用户类,先重写父类的菜单方法,定义一个供用户选择的 choice 根据选项实现不同的功能

public int menu() {
        System.out.println("===========普通用户的菜单===========");
        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;
    }

⑥.帮助父类进行构造,这里也把操作数组进行初始化,根据菜单的编号的顺序(注意这里一定要保证顺序否则实现的操作对不上号)去实例化

public NormalUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }

⑦.定义一个管理员类,编写的方法和上方一致(不赘述),在初始化操作数组的时候,实例化的对象不一致(二者实现的操作不一样),

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

步骤五、①.定义程序的入口,先定义一个 login 登录方法,这个方法主要判断的是此人的身份,所以这里的返回值是一个 User 类,根据选项去返回不同的身份

public static User login(){
        System.out.println("输入姓名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("身份识别:0--->用户 || 1--->管理员");
        int chioce = scanner.nextInt();
        if(chioce == 0){
            return new NormalUser(name);
        }
        else{
            return new AdminUser(name);
        }
    }

②.主方法中实例化一个书架,调用登录方法,返回的是一个对象,这里使用 User 类去结束这里发生向上转型,父类引用子类对象,循环去实现对书架的操作,通过 user 去访问子类的菜单(动态绑定),这时候的 user 是 NormalUser / AdminUser 所以通过 doWork 去实现各自不同的操作即可,这里传入选择的操作以及顺序表本身(操作的是顺序表)

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

3️⃣ 源代码

一、book包

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

    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 getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public String getType() {
        return type;
    }

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

    public boolean isBorrow() {
        return isBorrow;
    }

    public void setBorrow(boolean borrow) {
        isBorrow = borrow;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", money=" + money +
                ", type='" + type + '\'' +
                ((isBorrow == true) ? " 该书未在馆 " : " 该书在馆 ") +
                '}';
    }
}
package book;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Lenovo
 * Date: 2021-11-21
 * Time: 10:52
 */
public class BookList {
    private Book[] books = new Book[10];
    private int usedSize;

    public BookList() {
        books[0] =  new Book("三国演义","罗贯中",17,"小说");
        books[1] = new Book("西游记","吴承恩",47,"小说");
        books[2] = new Book("水浒传","施耐庵",37,"小说");
        usedSize = 3;
    }

    public int getUsedSize() {
        return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }
    public Book getBook(int pos){
        if (pos < 0 || pos > usedSize){
            System.out.println("位置不合法");
            return null;
        }
        return books[pos];
    }
    public void setBook(int pos, Book book){
        if (pos < 0 || pos > usedSize){
            System.out.println("位置不合法");
            return;
        }
        this.books[pos] = book;
    }
}

二、操作包(上面都是整理的展示)

三、用户包

package user;

import operation.*;

import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Lenovo
 * Date: 2021-11-21
 * Time: 11:14
 */
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("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;
    }
}

package user;

import operation.*;

import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Lenovo
 * Date: 2021-11-21
 * Time: 11:15
 */
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("===========普通用户的菜单===========");
        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;
    }
}

package user;

import book.Book;
import book.BookList;
import operation.IOperation;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Lenovo
 * Date: 2021-11-21
 * Time: 11:14
 */
public abstract class User {
     public abstract int menu();
     protected String name;
     public User(String name) {
        this.name = name;
    }
    protected IOperation[] iOperations;
     public void doWork(int choice, BookList bookList){
         iOperations[choice].work(bookList);
     }

}

四、程序入口

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

import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Lenovo
 * Date: 2021-11-21
 * Time: 11:03
 */
public class Main {
    public static User login(){
        System.out.println("输入姓名");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("身份识别:0--->用户 || 1--->管理员");
        int chioce = scanner.nextInt();
        if(chioce == 0){
            return new NormalUser(name);
        }
        else{
            return new AdminUser(name);
        }
    }
    public static void main(String[] args) {
        BookList bookList = new BookList();
        User user = login();
        while (true)
        {
            int choice = user.menu();
            user.doWork(choice,bookList);
        }
    }
}


此项目用于到了很多知识,基本博主的往期博客都有讲解,需要的关注博主主页,如果有帮助还请一键三连

💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦の澜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值