图书管理系统——Java实现

文章目录

  • Java实现图书管理系统
    • 问题分析
    • 框架搭建
    • 业务实现
    • 项目测试
    • 代码演示
      • Book
      • ioperation
      • User
      • Main(默认包)

Java实现图书管理系统

学习了前六篇的SE语法,我们现在要用它们实现一个简单的图书管理系统项目,深入了解各个知识点的应用场景。我们将整个过程分为四大部分:

  • 问题分析
  • 框架搭建
  • 业务实现
  • 项目测试

其中,框架搭建最为重要且难以理解,涉及类、接口等之间的复杂关系。


问题分析

我们期望实现一个不同身份操作界面不同的图书管理系统。

而要使用面向对象的思想实现该项目,第一步肯定是找对象

初步分析,我们的项目会包含以下对象:

  1. :书的属性
  2. 用户:用户又分为普通用户和管理员

单一的书对象太过分散不好维护,所以我们决定添加一个新类书架,书架中有若干的书对象,我们后期操作的对象就是书架。

(以下所有代码块的内容不一定是完成版,我们会在解决问题的过程中不断改进之前的代码)


【书、书架】

我们先实现书类

其中,我们用private修饰书类的成员变量,尽可能体现Java的封装性,同时添加getset方法;

图书系统少不了图书信息的打印,为了方便打印,我们选择重写toString方法,注意boolean类型的打印,它指示书的借阅情况,如果仅打印truefalse,不利于用户理解,所以我们做出一些改动如下代码中可见:

//Book.java
package Book;


public class Book {
    private String name;//书名
    private String author;//作者
    private double price;//价格
    private String kind;//类型
    private boolean borrow;//借阅情况

    //构造方法
    public Book(String name, String author, double price, String kind) {
        this.name = name;
        this.author = author;
        this.price = price;
        this.kind = kind;
    }

    //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 double getPrice() {
        return price;
    }

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

    public String getKind() {
        return kind;
    }

    public void setKind(String kind) {
        this.kind = kind;
    }

    public boolean isBorrow() {
        return borrow;
    }

    public void setBorrow(boolean borrow) {
        this.borrow = borrow;
    }

    //重写toString
    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", kind='" + kind + '\'' +
                " " + (borrow == true ? "已借阅" : "未借阅") +
                '}';
    }
}

接下来是书架

书架里有若干书,书架与书的关系是:A has B的关系,所以我们考虑到使用组合

仍然使用private修饰成员变量,并给出getset方法。

//BookList.java
package Book;


public class BookList {
    private Book[] books = new Book[10];//组合
    private int size;//书的数量

    //构造方法初始化书架
    public BookList() {
        //初始给两本书
        this.books[0] = new Book("三国演义", "罗贯中", 23, "小说");
        this.books[1] = new Book("红楼梦", "曹雪芹", 23, "小说");
        this.size = 2;
    }

    public Book getBook(int pos) {
        return this.books[pos];
    }

    public void setBook(Book book) {
        this.books[this.size] = book;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

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

【用户】

分析: 用户分为两种,管理员和普通用户,符合A is B的关系,即普通用户或管理员是用户,所以用户部分可以实现继承关系,将两种身份的共性进行抽取,简化代码。

用户类

实际上,我们并不会实例化一个用户的对象,因为用户要指名身份,所以我们考虑将User类设计成抽象类

并将其成员变量尽可能地封装。

//User.java
package User;
import Book.BookList;
import ioperation.IOperation;


public abstract class User {
    public String name;

    //构造方法
    public User(String name) {
        this.name = name;
    }
   
}

普通用户管理员的代码类似,我们一并实现:

//AdminUser.java
package User;
import ioperation.*;
import java.util.Scanner;


public class AdminUser extends User {
    
    //构造方法先利用super初始化父类成员
    public AdminUser(String name) {
        super(name);
    }
}
//NormalUser.java
package User;
import ioperation.*;
import java.util.Scanner;


public class NormalUser extends User {
    
    //构造方法先利用super初始化父类成员
    public NormalUser(String name) {
        super(name);
    }
}

到这里,我们实现了几个基本的类,后续也会一一完善,问题分析告一段落,我们直接进入框架搭建模块,这里是项目的难点。


框架搭建

我们先模拟一下项目执行过程:

程序启动 ——> 用户输入信息(登录) ——> 程序根据用户身份展示不同的操作页面 ——> 用户输入操作 ——> 程序执行 ——> … …

——> 程序终止

基于上面的模拟过程,我们开始一步一步搭建框架:


在已有实现类的基础上,我们先实现登录的逻辑,自定义方法名:login

这部分是我们框架的开始,是用户最先看到的画面,我们期望登陆方法能够:

  • 实现用户选择身份的交互
  • 返回可操作的对象:返回值有两种情况,而返回的对象的类共同继承了User类,所以我们选择将方法返回值设置成User类,这里即体现了向上转型
    public static User login() {
        System.out.println("请输入您的名字:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("请输入您的身份:1. 管理员  2. 普通用户");
        int choice = scanner.nextInt();
        if(choice == 1) {
            return new AdminUser(name);
        }else {
            return new NormalUser(name);
        }
    }

我们拿到了用户身份,接下来我们要据此给出相应的菜单:

不同的身份,打印不同的菜单,符合多态的思想:

我们在父类中定义抽象方法menu,两个子类重写menu方法,然后用父类引用访问重写后的menu方法,即可实现多态:

关于menu方法,我们不只期望它可以打印菜单,我们期望它打印菜单的同时可以与用户交互,拿到用户的选择并返回等待进一步的操作。(菜单的打印自行发挥,菜单中的操作就是后面要实现的业务)

  1. 拓展父类User

    //User.java
    package User;
    import Book.BookList;
    import ioperation.IOperation;
    
    
    public abstract class User {
        public String name;
    
        public User(String name) {
            this.name = name;
        }
        
        //待重写的抽象方法
        public abstract int menu();
    }
    
  2. 子类AdminUserNormalUser重写menu方法

    //AdminUser.java
    package User;
    import ioperation.*;
    import java.util.Scanner;
    
    
    public class AdminUser extends User {
        public AdminUser(String name) {
            super(name);
        }
    
        @Override
        public int menu() {
            System.out.println("欢迎" + this.name + "使用图书管理系统");
            System.out.println("********管理员菜单********");
            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.println("*************************");
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入您的操作:");
            int choice = scanner.nextInt();
            if(choice < 0 || choice > 4) {
                return -1;
            }
            return choice;
        }
    }
    
    //NormalUser.java
    package User;
    import ioperation.*;
    import java.util.Scanner;
    
    
    public class NormalUser extends User {
        public NormalUser(String name) {
            super(name);
        }
    
        @Override
        public int menu() {
            System.out.println("欢迎" + this.name + "使用图书管理系统");
            System.out.println("********普通用户菜单********");
            System.out.println("*************************");
            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);
            System.out.println("请输入您的操作:");
            int choice = scanner.nextInt();
            if(choice < 0 || choice > 3) {
                return -1;
            }
            return choice;
        }
    }
    

此处暂停,我们梳理一下我们已经实现的逻辑:

体现在Main类中的main方法中:

//Main.java
import Book.BookList;
import User.*;
import java.util.Scanner;


public class Main {
    
    //登录方法
    public static User login() {
        System.out.println("请输入您的名字:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("请输入您的身份:1. 管理员  2. 普通用户");
        int choice = scanner.nextInt();
        if(choice == 1) {
            return new AdminUser(name);
        }else {
            return new NormalUser(name);
        }
    }
    
    //main方法
    public static void main(String[] args) {
        //创建书架
        BookList bookList = new BookList();

        //登录并确定用户类型返回
        User user = login();

        while (true) {
            //根据用户类型打印菜单并返回用户操作选择
            int choice = user.menu();
            if(choice < 0) {
                System.out.println("输入非法,请重新输入!");
            }else {
                //根据用户选择执行相关操作
                //......
            }
        }
    }
}

最后一部分逻辑,也是最难理解的一部分:根据用户选择调用指定操作

我们当然可以选择在Main类中一次性实现所有的操作方法并调用,但这样书写代码的缺陷是非逻辑代码大量集中,不方便维护,同时也没有利用Java的优点。

我们给出下面的解决方案:

  1. 创建一个接口,规范所有操作
  2. 创建若干操作类,实现规范接口

创建规范接口

//IOperation.java
package ioperation;
import Book.BookList;


public interface IOperation {
    //工作方法
    void work(BookList bookList);
}


根据菜单创建若干的操作类(这里仅给出逻辑代码,具体的操作在 业务实现 模块实现)

//AddOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;

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

//DelOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;

public class DelOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书...");
    }
}

//FindOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;

public class FindOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("查找图书...");
    }
}

//ShowOperation.java
package ioperation;
import Book.*;

public class ShowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("展示图书...");
    }
}

//BorrowOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;

public class BorrowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书...");
    }
}

//ReturnOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;

public class ReturnOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书...");
    }
}

//ExitOperation.java
package ioperation;
import Book.BookList;

public class ExitOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统...");
    }
}


仅实现以上代码并不能将用户(login方法返回值)、用户选择(menu方法返回值)、操作(上代码)联系起来

我们采取这样的解决方案:

  • 在父类User中添加成员变量,其类型是IOperation[]
  • 分别使子类AdminUserNormalUser的构造方法可以初始化父类的IOperation[]类型的成员,这样,我们在实例化子类对象时,就构建好了这样一个数组
  • 在父类User中创建操作方法,父类引用调用此方法,并在此方法中再调用指定操作类中的重写方法
  • 我们的项目的各种操作都是针对BookList(书架)的,所以我们的参数列表要大量出现BookList类对象

完善后的父类User

//User.java
package User;
import Book.BookList;
import ioperation.IOperation;


public abstract class User {
    public String name;
    protected IOperation[] iOperations;//新添成员变量

    public abstract int menu();

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

    //新添操作方法
    public void doOperation(int choice, BookList bookList) {
        this.iOperations[choice].work(bookList);
    }
}

完善后的子类

//AdminUser.java
package User;
import ioperation.*;
import java.util.Scanner;


public class AdminUser extends User {
    public AdminUser(String name) {
        super(name);
        //根据管理员菜单进行初始化
        this.iOperations = new IOperation[]{
                new ExitOperation(),
                new AddOperation(),
                new DelOperation(),
                new FindOperation(),
                new ShowOperation(),
        };
    }

    @Override
    public int menu() {
        System.out.println("欢迎" + this.name + "使用图书管理系统");
        System.out.println("********管理员菜单********");
        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.println("*************************");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的操作:");
        int choice = scanner.nextInt();
        if(choice < 0 || choice > 4) {
            return -1;
        }
        return choice;
    }
}
//NormalUser.java
package User;
import ioperation.*;
import java.util.Scanner;


public class NormalUser extends User {
    public NormalUser(String name) {
        super(name);
        //根据普通用户菜单进行初始化
        this.iOperations = new IOperation[]{
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }

    @Override
    public int menu() {
        System.out.println("欢迎" + this.name + "使用图书管理系统");
        System.out.println("********普通用户菜单********");
        System.out.println("*************************");
        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);
        System.out.println("请输入您的操作:");
        int choice = scanner.nextInt();
        if(choice < 0 || choice > 3) {
            return -1;
        }
        return choice;
    }
}

框架最后一步:完善main方法:

//Main.java
import Book.BookList;
import User.*;
import java.util.Scanner;


public class Main {
    public static User login() {
        System.out.println("请输入您的名字:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("请输入您的身份:1. 管理员  2. 普通用户");
        int choice = scanner.nextInt();
        if(choice == 1) {
            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();
            if(choice < 0) {
                System.out.println("输入非法,请重新输入!");
            }else {
                //根据用户选择执行相关操作
                user.doOperation(choice, bookList);
            }
        }
    }
}

业务实现

完成了框架搭建,业务实现就简单多了,业务实现仅需要将实现操作接口的操作类的重写方法完善即可。

【添加图书】

判断书架是否满 ——> 判断新书是否重复 ——> 添加

//AddOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;


public class AddOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("添加图书...");
        //判断书架是否已满
        int size = bookList.getSize();
        if(size == 10) {
            System.out.println("书架满了...");
            return;
        }
        Book[] books = bookList.getBooks();
        Scanner scanner = new Scanner(System.in);
        //判断新书是否重复
        System.out.println("请输入书名;");
        String name = scanner.nextLine();
        for (int i = 0; i < size; i++) {
            if(name.equals(books[i].getName())) {
                System.out.println("已存在这本书!");
                return;
            }
        }
        System.out.println("请输入作者:");
        String author = scanner.nextLine();
        System.out.println("请输入价格:");
        int price = scanner.nextInt();
        //这里要注意,要读走回车,否则类型kind接受的是回车
        //或者让用户先输入类型,也可以解决这一问题
        String tmp = scanner.nextLine();

        System.out.println("请输入类型:");
        String kind = scanner.nextLine();

        Book book = new Book(name, author, price, kind);
        bookList.setBook(book);
        bookList.setSize(size + 1);

    }
}

【删除图书】

判断书架是否为空 ——> 寻找指定图书 ——> 根据寻找结果进行相关操作

//DelOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;


public class DelOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书...");
        //判断书架是否为空
        int size = bookList.getSize();
        if(size == 0) {
            System.out.println("书架为空!");
            return;
        }
        //输入信息
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要删除的书名:");
        String name = scanner.nextLine();

        //删除
        Book[] books = bookList.getBooks();
        for (int i = 0; i < size; i++) {
            if(books[i].getName().equals(name)) {
                books[i] = null;
                for (int j = i; j < size - 1; j++) {
                    books[j] = books[j + 1];
                }
                bookList.setSize(size - 1);
                System.out.println("删除成功!");
                return;
            }
        }
        System.out.println("没有查询到指定的书!");
    }
}

【查找图书】

输入信息 ——> 查找 ——> 成功则打印

//FindOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;


public class FindOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("查找图书...");
        int size = bookList.getSize();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要查询的书名:");
        String name = scanner.nextLine();

        Book[] books = bookList.getBooks();
        for (int i = 0; i < size; i++) {
            if(books[i].getName().equals(name)) {
                System.out.println("查找成功,信息如下:");
                System.out.println(books[i].toString());
                return;
            }
        }
        System.out.println("没有查询到指定的书!");
    }
}

【展示图书】

判断书架是否为空 ——> 展示图书

//ShowOperation.java
package ioperation;
import Book.*;


public class ShowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("展示图书...");
        int size = bookList.getSize();
        if(size == 0) {
            System.out.println("书架为空!");
            return;
        }
        Book[] books = bookList.getBooks();

        for (int i = 0; i < size; i++) {
            System.out.println(books[i].toString());
        }
    }
}

【借阅图书】

输入信息 ——> 查找图书 ——> 借阅成功或失败(借阅成功,将Book对象的borrow成员设置成true即可)

//BorrowOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;


public class BorrowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书...");
        int size = bookList.getSize();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要借阅的书名:");
        String name = scanner.nextLine();

        Book[] books = bookList.getBooks();
        for (int i = 0; i < size; i++) {
            if(books[i].getName().equals(name)) {
                if(!books[i].isBorrow()) {
                    System.out.println("借阅成功!");
                    books[i].setBorrow(true);
                    return;
                }else {
                    System.out.println("该书已被借阅!");
                    return;
                }
            }
        }
        System.out.println("没有查询到指定的书!");
    }
}

【归还图书】

输入信息 ——> 检查借阅情况 ——> 归还或打印其他信息(归还成功,将Book对象的borrow成员设置成false即可)

//ReturnOperation.java
package ioperation;
import Book.*;
import java.util.Scanner;


public class ReturnOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书...");
        int size = bookList.getSize();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要归还的书名:");
        String name = scanner.nextLine();

        Book[] books = bookList.getBooks();
        for (int i = 0; i < size; i++) {
            if(books[i].getName().equals(name)) {
                if(!books[i].isBorrow()) {
                    System.out.println("这本书还没有被借阅呢,无法归还,请检查是否输入错误!");
                    return;
                }else {
                    System.out.println("归还成功!");
                    books[i].setBorrow(false);
                    return;
                }
            }
        }
        System.out.println("没有查询到指定的书!");
    }
}

【退出系统】

//ExitOperation.java
package ioperation;
import Book.BookList;


public class ExitOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统...");
        System.exit(0);
    }
}

项目测试

【登录测试】

在这里插入图片描述
在这里插入图片描述


【操作演示(部分)】

在这里插入图片描述

其他操作均可正常运行,大家下来可以自己实现一下。


代码演示

演示代码分布在多个包中:

  1. Book:包含书、书架对象
  2. ioperation:包含操作接口以及实现操作接口的类
  3. User:包含用户(父类)、管理员、普通用户类
  4. Main(默认包):代码总逻辑,使用上三部分代码

在这里插入图片描述

Book

//Book.java
package Book;

public class Book {
    private String name;
    private String author;
    private double price;
    private String kind;
    private boolean borrow;

    public Book(String name, String author, double price, String kind) {
        this.name = name;
        this.author = author;
        this.price = price;
        this.kind = kind;
    }

    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 double getPrice() {
        return price;
    }

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

    public String getKind() {
        return kind;
    }

    public void setKind(String kind) {
        this.kind = kind;
    }

    public boolean isBorrow() {
        return borrow;
    }

    public void setBorrow(boolean borrow) {
        this.borrow = borrow;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", kind='" + kind + '\'' +
                " " + (borrow == true ? "已借阅" : "未借阅") +
                '}';
    }
}

//BookList.java
package Book;

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

    public BookList() {
        //初始给两本书
        this.books[0] = new Book("三国演义", "罗贯中", 23, "小说");
        this.books[1] = new Book("红楼梦", "曹雪芹", 23, "小说");
        this.size = 2;
    }

    public Book getBook(int pos) {
        return this.books[pos];
    }

    public void setBook(Book book) {
        this.books[this.size] = book;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

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

ioperation

//IOperation.java
package ioperation;

import Book.BookList;

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

//AddOperation.java
package ioperation;

import Book.Book;
import Book.BookList;

import java.util.Scanner;

public class AddOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("添加图书...");
        int size = bookList.getSize();
        if(size == 10) {
            System.out.println("书架满了...");
            return;
        }
        Book[] books = bookList.getBooks();
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入书名;");
        String name = scanner.nextLine();
        for (int i = 0; i < size; i++) {
            if(name.equals(books[i].getName())) {
                System.out.println("已存在这本书!");
                return;
            }
        }
        System.out.println("请输入作者:");
        String author = scanner.nextLine();
        System.out.println("请输入价格:");
        int price = scanner.nextInt();
        //读走回车
        String tmp = scanner.nextLine();

        System.out.println("请输入类型:");
        String kind = scanner.nextLine();

        Book book = new Book(name, author, price, kind);
        bookList.setBook(book);
        bookList.setSize(size + 1);

    }
}

//DelOperation.java
package ioperation;

import Book.Book;
import Book.BookList;

import java.util.Scanner;

public class DelOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书...");
        int size = bookList.getSize();
        if(size == 0) {
            System.out.println("书架为空!");
            return;
        }
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要删除的书名:");
        String name = scanner.nextLine();

        Book[] books = bookList.getBooks();
        for (int i = 0; i < size; i++) {
            if(books[i].getName().equals(name)) {
                books[i] = null;
                for (int j = i; j < size - 1; j++) {
                    books[j] = books[j + 1];
                }
                bookList.setSize(size - 1);
                System.out.println("删除成功!");
                return;
            }
        }
        System.out.println("没有查询到指定的书!");
    }
}

//FindOperation.java
package ioperation;

import Book.*;

import java.util.Scanner;

public class FindOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("查找图书...");
        int size = bookList.getSize();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要查询的书名:");
        String name = scanner.nextLine();

        Book[] books = bookList.getBooks();
        for (int i = 0; i < size; i++) {
            if(books[i].getName().equals(name)) {
                System.out.println("查找成功,信息如下:");
                System.out.println(books[i].toString());
                return;
            }
        }
        System.out.println("没有查询到指定的书!");
    }
}

//ShowOperation.java
package ioperation;

import Book.BookList;
import Book.Book;

public class ShowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("展示图书...");
        int size = bookList.getSize();
        if(size == 0) {
            System.out.println("书架为空!");
            return;
        }
        Book[] books = bookList.getBooks();

        for (int i = 0; i < size; i++) {
            System.out.println(books[i].toString());
        }
    }
}

//BorrowOperation.java
package ioperation;

import Book.Book;
import Book.BookList;

import java.util.Scanner;

public class BorrowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书...");
        int size = bookList.getSize();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要借阅的书名:");
        String name = scanner.nextLine();

        Book[] books = bookList.getBooks();
        for (int i = 0; i < size; i++) {
            if(books[i].getName().equals(name)) {
                if(!books[i].isBorrow()) {
                    System.out.println("借阅成功!");
                    books[i].setBorrow(true);
                    return;
                }else {
                    System.out.println("该书已被借阅!");
                    return;
                }
            }
        }
        System.out.println("没有查询到指定的书!");
    }
}

//ReturnOperation.java
package ioperation;

import Book.Book;
import Book.BookList;

import java.util.Scanner;

public class ReturnOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书...");
        int size = bookList.getSize();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要归还的书名:");
        String name = scanner.nextLine();

        Book[] books = bookList.getBooks();
        for (int i = 0; i < size; i++) {
            if(books[i].getName().equals(name)) {
                if(!books[i].isBorrow()) {
                    System.out.println("这本书还没有被借阅呢,无法归还,请检查是否输入错误!");
                    return;
                }else {
                    System.out.println("归还成功!");
                    books[i].setBorrow(false);
                    return;
                }
            }
        }
        System.out.println("没有查询到指定的书!");
    }
}

//ExitOperation.java
package ioperation;

import Book.BookList;

public class ExitOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统...");
        System.exit(0);
    }
}

User

//User.java
package User;

import Book.BookList;
import ioperation.IOperation;

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

    public abstract int menu();

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

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

//AdminUser.java
package User;

import ioperation.*;

import java.util.Scanner;

public class AdminUser extends User {
    public AdminUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{
                new ExitOperation(),
                new AddOperation(),
                new DelOperation(),
                new FindOperation(),
                new ShowOperation(),
        };
    }

    @Override
    public int menu() {
        System.out.println("欢迎" + this.name + "使用图书管理系统");
        System.out.println("********管理员菜单********");
        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.println("*************************");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的操作:");
        int choice = scanner.nextInt();
        if(choice < 0 || choice > 4) {
            return -1;
        }
        return choice;
    }
}

//NormalUser.java
package User;

import ioperation.*;

import java.util.Scanner;

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

    @Override
    public int menu() {
        System.out.println("欢迎" + this.name + "使用图书管理系统");
        System.out.println("********普通用户菜单********");
        System.out.println("*************************");
        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);
        System.out.println("请输入您的操作:");
        int choice = scanner.nextInt();
        if(choice < 0 || choice > 3) {
            return -1;
        }
        return choice;
    }
}

Main(默认包)

//Main.java
import Book.BookList;
import User.*;


import java.util.Scanner;

public class Main {
    public static User login() {
        System.out.println("请输入您的名字:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("请输入您的身份:1. 管理员  2. 普通用户");
        int choice = scanner.nextInt();
        if(choice == 1) {
            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();
            if(choice < 0) {
                System.out.println("输入非法,请重新输入!");
            }else {
                //根据用户选择执行相关操作
                user.doOperation(choice, bookList);
            }
        }
    }
}

当前实现的项目没有保存数据的能力,我们后面会使用数据库做到这一点。

这个项目的意义在于提高我们的编码能力、熟悉前面学习的SE语法的应用场景、同时增加学习的趣味性
希望我们大家多多练习,早日成才!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/664833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【CH32V305FBP6】4. systick 配置

配置 main.c void SYSTICK_Init_Config(u_int64_t ticks) {SysTick->SR & ~(1 << 0);//clear State flagSysTick->CMP ticks - 1;SysTick->CNT 0;SysTick->CTLR 0xF;NVIC_SetPriority(SysTicK_IRQn, 15);NVIC_EnableIRQ(SysTicK_IRQn); }中断计数 …

算法-扫描线

目录 什么是扫描线算法&#xff1f; 扫描线简单应用 更多的扫描线 什么是扫描线算法&#xff1f; 在计算几何中&#xff0c;扫描线算法&#xff08;scan line algorithm&#xff09;一般用来解决几何图形的面积交并&#xff0c;周长交并问题&#xff0c;扫描线算法的核心思想…

Day 8:1461. 检查一个字符串是否包含所有长度为 K 的二进制子串

Leetcode 1461. 检查一个字符串是否包含所有长度为 K 的二进制子串 给你一个二进制字符串 s 和一个整数 k 。如果所有长度为 k 的二进制字符串都是 s 的子串&#xff0c;请返回 true &#xff0c;否则请返回 false 。 截取每个长度为 k 的字符串&#xff0c;加入 Set 中&#x…

wpf listbox实现选中动画

效果如下&#xff1a; 参考&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers/blob/master/src/WPFDevelopers.Samples.Shared/Controls/NavigateMenu/NavigateMenu.xaml 实现上述效果的前台代码&#xff1a; <Windowx:Class"ListBox.MainWindow"…

数据隐私新篇章:Facebook如何保护用户信息

随着数字化时代的到来&#xff0c;数据隐私保护成为了社交媒体平台和用户共同关注的焦点。作为全球最大的社交网络之一&#xff0c;Facebook一直致力于保护用户的隐私和数据安全。本文将深入探讨Facebook在数据隐私保护方面的措施和实践&#xff0c;以及其如何开启数据隐私的新…

C++系列-类模板

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 类模板的定义格式&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; template<class T> class Stack { public:Stack(size_…

u盘文件保密的方法有哪些?关于U盘的使用你要知道这些!

U盘作为便携式的存储设备&#xff0c;被广泛应用于日常工作和生活中。 然而&#xff0c;U盘的丢失或被盗可能导致敏感数据泄露&#xff0c;因此&#xff0c;掌握U盘文件保密的方法至关重要。 本文将介绍几种有效的U盘文件保密方法&#xff0c;并分享关于U盘使用的关键知识&…

BioVendor—Surfactant Protein D Human ELISA

人表面活性剂蛋白D是糖蛋白和钙依赖凝集素胶原亚家族的一员。SP-D是一种同源三聚体蛋白&#xff0c;由三个43kDa单元组成&#xff0c;这些单元在它们的中间结合。大多数SP-D主要含有十二聚体(四个三聚体亚单位)&#xff0c;但也观察到更高的多聚体。每个单元由至少四个离散的结…

旧衣回收小程序带来的收益优势,小程序有哪些功能?

随着互联网的快速发展&#xff0c;大众对旧衣回收市场也越来越了解&#xff0c;对于闲置的旧衣物也有了适合的处理方式。旧衣回收也符合了当下资源回收利用&#xff0c;因此&#xff0c;旧衣回收市场获得了爆发式增长&#xff0c;市场规模不断扩大。同时市场中还吸引了越来越多…

记录岁月云明细账excel导出的性能优化

财务软件报表还是非常麻烦&#xff0c;因为使用excel最好的就是财务&#xff0c;但是通过java导出excel&#xff0c;使用easyexcel不用报表工具&#xff0c;不是这么容易。采用jprofile对一个导出操作进行监控&#xff0c;其中一家零售企业导出当月全部明细账&#xff0c;检测到…

MySQL数据库--从创建数据库到删库跑路

目录 MySQL安装: 1. 数据库基本操作1.1 创建数据库1.2 显示当前数据库1.3 删除数据库1.4 使用数据库/选中数据库 2. SQL中的数据类型2.1 数值类型2.2 字符串类型2.3 时间类型 3. 表的操作3.2 创建表3.1 显示数据库中的表3.3 查看表的详细情况3.4 删除表3.5 注释3. 修改列(了解即…

dubbo复习:(18)服务端Filter

用来在服务响应返回到客户端之前进行额外处理。 一、定义Filter package cn.edu.tju.config;import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Invocation; import org.apache.du…

检定记录内容解析:非红外二氧化硫气体检测仪的维护与验证

在工业生产与环境保护中&#xff0c;二氧化硫作为一种常见的有害气体&#xff0c;其浓度的监测和控制显得尤为重要。 非红外二氧化硫气体检测仪以其独特的检测原理和高灵敏度&#xff0c;在二氧化硫监测领域发挥着不可或缺的作用。 在这篇文章中&#xff0c;佰德将详细介绍非…

神经网络与深度学习——第4章 前馈神经网络

本文讨论的内容参考自《神经网络与深度学习》https://nndl.github.io/ 第4章 前馈神经网络 前馈神经网络 神经元 Sigmoid型函数 Hard-Logistic函数和Hard-Tanh函数 ReLU函数 带泄露的ReLU 带参数的ReLU ELU函数 Softplus函数 Swish函数 GELU函数 Maxout单元 网络结构 前馈网络…

CentOS 7基础操作02_优化Linux操作系统中的服务

1、实验环境 公司在文件服务器中新安装了CentOS系统.由于默认启动的服务程序较多&#xff0c;系统运行缓慢。现需要对系绞服务进行适当优化&#xff0c;减少一些不必要的自启动服务.并设置系统在开机后直接进入字符模式。 2、需求描述 根据实际使用需求对CentOS 7操作系统中的…

PLC无线通讯模块

在工业自动化日益深入的今天&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;作为工业控制的核心大脑&#xff0c;其功能的扩展和智能化水平直接影响着整个生产线的效率和安全性。而PLC无线通讯模块&#xff0c;作为连接PLC与外界信息世界的桥梁&#xff0c;其重要性不…

揭秘Python:下划线的特殊用法,你绝对想不到!

在Python编程中&#xff0c;下划线&#xff08;underscore&#xff09;是一个常见而又强大的工具。它不仅仅是一个普通的字符&#xff0c;而是具有特殊含义和用法的符号。今天&#xff0c;我们就来揭开Python下划线的神秘面纱&#xff0c;探索它的各种妙用。 下划线的基本用法…

前端html-docx实现html转word,并导出文件,文字+图片

前端html-docx实现html转word&#xff0c;并导出文件 前端web页面 有文字&#xff0c;有图片&#xff0c;保存web的css效果 使用工具&#xff1a;html-docx 官方网址&#xff1a;http://docs.asprain.cn/html-docx/readme.html 步骤&#xff1a; 1 npm install html-docx-js…

边缘网关在数据采集方面发挥的作用-天拓四方

随着物联网技术的快速发展&#xff0c;边缘网关作为连接物理世界与数字世界的桥梁&#xff0c;其重要性日益凸显。特别是在数据采集方面&#xff0c;边缘网关以其独特的优势&#xff0c;为物联网系统的运行和管理提供了强大的支持。本文将从边缘网关的基本概念、数据采集流程、…

vcruntime140_1.dll在哪个文件夹?详细修复vcruntime140_1.dll缺失的方法

vcruntime140_1.dll文件是什么&#xff1f;相信很多人都对它很陌生吧&#xff1f;毕竟大部分人对于dll文件还是了解得太少了&#xff0c;当突发情况出现vcruntime140_1.dll文件丢失&#xff1f;你要怎么办&#xff1f;不要担心&#xff0c;下面我们就来给大家详细的讲解一下修复…