【JavaProject】经典图书管理系统

JavaProject & 经典图书管理系统

  • 我们学习了一些java基础语法之后,以及了解到了面向对象的三大特征之后,我们结合这些知识,来实践一下吧!

图书管理功能大体要求:

  1. 一本书有不同属性
    • 书名
      • 也可将书名跟书内容联系起来,附上字符串链接(这里我省略了)
    • 书类
    • 价格
    • 作者
    • 是否被借
    • 借书之人
  2. 所有书放在 书架(数组)
  3. 来访者的身份
    • 管理员
    • 普通用户
  4. 不同身份的权限
    • 管理员
      • 添书
      • 删书
      • 查书
      • 查看书单
      • 退出系统
    • 普通用户
      • 查书
      • 借书
      • 还书
      • 退出系统

根据要求制作模板:

Ⅰ.构建Book类
  • 基本属性
public class Book {
    private String name;
    private String author;
    private Double price;
    private String type;
    private boolean state;
    private String Borrower;
}
  • 基本方法
    • 不必害怕,只不过是一些构造方法getter()setter()以及重写toString
    • IDEA有快捷方式—> Alt + Enter
    public String getBorrower() {
        return Borrower;
    }
    public void setBorrower(String borrower) {
        Borrower = borrower;
    }
    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ", " + (state ? "已被借出" : "未被借出") +
                '}';
    }
    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 getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public boolean isState() {
        return state;
    }
    public void setState(boolean state) {
        this.state = state;
    }
    public Book(String name, String author, Double price, String type) {
        this.name = name;
        this.author = author;
        this.price = price;
        this.type = type;
    }
Ⅱ. 进入系统页面基本操作&菜单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FltjnZlS-1676363147523)(C:\Users\20404\AppData\Roaming\Typora\typora-user-images\image-20230214145500292.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7g1B0HiO-1676363147524)(C:\Users\20404\AppData\Roaming\Typora\typora-user-images\image-20230214145521933.png)]

  • 如上图的管理员菜单普通用户菜单【管理员可以设立密码】
Ⅲ. 书架搭建
  • 默认三本书
  • 满了就动态扩容—>参考Java数组章节
public class BookList {
    private Book[] books = new Book[5];
    private int number = 3;
    private int capacity = 5;
    {
        books[0] = new Book("小王子1", "王子1", 99.9, "学习");
        books[1] = new Book("小王子2", "王子2", 99.9, "学习");
        books[2] = new Book("小王子3", "王子3", 99.9, "学习");
    }
}
  • 调整toString()方法
    @Override 
	public String toString() {
        String str = "";
        for (int i = 0; i < number; i++) {
            str += "\n" + books[i];
        }
        return str + '\n';
    }
  • 基本方法

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

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

    public int getCapacity() {
        return capacity;
    }

    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }
  • 自定义设置方法
    public Book[] getBooks() {
        return books;
    }
    public Book getBooks(int pos) {
        return books[pos];
    }

    public void setBooks(Book book, int pos) {
        this.books[pos] = book;
    }

1. 通过输入1 / 2 确定身份

  • 先看代码:
    • (这里我并没有设置完全退出系统(并且一个人在系统中,可以一直操作,直到退出),而是让之后的人继续进入,并且书架的书不变)
public class Main {
    public static User judge(int role, String name) {
        return role == 1 ? new Admin(name) : new Normal(name);
    }
    public static void main(String[] args) {
        BookList bookList = new BookList();
        while(true) {
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入你的名字:>");
            String name = scanner.nextLine();
            System.out.println("1. 管理员\n2. 普通用户");
            System.out.print("请输入你的身份:>");
            int role = scanner.nextInt();
            User user = judge(role, name);
            user.menu(bookList);
 		}
    }
}
public abstract class User {
    protected String name;
    public abstract void menu(BookList bookList);
    public User(String name) {
        this.name = name;
    }
}
public class Admin extends User {
    //继承User
}
public class Normal extends User {
    //继承User
}
  •             User user = judge(role, name);
                user.menu(bookList);
    
  • public static User judge(int role, String name) {
            return role == 1 ? new Admin(name) : new Normal(name);
        }
    
  • 这两段可能比较难理解

  • 其实就是根据 输入role判断judge()返回什么类型的实例化

    • 从而完成向上转型
    • 从而根据实例化对象重写menu()方法
    • 再用user重写后的menu()方法

2. 操作接口 - IOpera

public interface IOpera {
    public void work(BookList bookList,  String person);
    //待重写方法
    //这里的person指的是使用之人
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WfRGvqIg-1676363147524)(C:\Users\20404\AppData\Roaming\Typora\typora-user-images\image-20230214153230316.png)]

2.1 根据上图实现接口重写方法

  • 个人习惯一个类一个java文件
2.1.1 Add 添加书籍
  • 这里我将【行输入】都放前面的原因
    • 因为其他输入需要将多吃的回车先去掉,才能继续输入,不然接下来的行输入会错误的取到'\n'
    • 太过麻烦
public class Add implements IOpera{
    @Override
    public void work(BookList bookList, String s) { //这里的s并没有实际意义,只是为了满足重写要求
        //输入书的信息
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要添加的书名:>");
        String name = scanner.nextLine();
        System.out.print("请输入这本书的作者:>");
        String author = scanner.nextLine();
        System.out.print("请输入这本书的类别:>");
        String type = scanner.nextLine();
        System.out.print("请输入这本书的价格:>");
        Double price = scanner.nextDouble();
        
        //拿到书
        Book book = new Book(name, author, price, type);
        
        //放入书架
        bookList.setBooks(book, bookList.getNumber());
        bookList.setNumber(bookList.getNumber() + 1);
        
        //扩容机制
        if(bookList.getCapacity() == bookList.getNumber()) {
            bookList.setCapacity(bookList.getCapacity() + 5);
            Book[] books = Arrays.copyOf(bookList.getBooks(), bookList.getCapacity());
            bookList.setBooks(books);
        }
        
        System.out.println("添加成功!");
    }
}
2.1.2 Del - 删除书籍
  • **删除机制:**找出待删除的下标,将后面的东西往前挪动覆盖
    • 必须使用从头往前挪
  • 这里用到的查找下标方法来自接下来的Search类
  • 在这里还有一个功能,就是删的书被借走,应该找那个人要回
public class Del implements IOpera{
    @Override
    public void work(BookList bookList,  String person) {
        System.out.print("请输入你要删除的书:>");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        
        int index = Search.search(bookList, name);
        
        if(index != -1) {
            
            if(bookList.getBooks(index).isState()) {
                System.out.println("此书被借出,无法删除");
                System.out.println("请找" + bookList.getBooks(index).getBorrower() + "要回此书");
                return;
            }
            
            System.out.println("删除成功");
            bookList.setBooks(null, index);
            for (int i = index + 1; i < bookList.getNumber(); i++) {
                bookList.setBooks(bookList.getBooks(i), i - 1);
                bookList.setBooks(null, i);
            }
            bookList.setNumber(bookList.getNumber() - 1);
        }else {
            System.out.println("找不到你要删除的书");
        }
    }
}
4.1.3 Search - 查看书籍
  • 遍历找书即可
public class Search implements IOpera{
    public static int search(BookList bookList, String name) {
        for (int i = 0; i < bookList.getNumber(); i++) {
            if(bookList.getBooks()[i].getName().equals(name)) {
                return i;
            }
        }
        return -1;
    }
    @Override
    public void work(BookList bookList, String person) {
        System.out.print("请输入你想查询的书:>");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int index = search(bookList, name);
        if(index != -1) {
            System.out.println("找到了");
            System.out.println(bookList.getBooks()[index]);
        }else {
            System.out.println("未能找到");
        }
    }
}
2.1.4 Show - 展示书单
  • 打印书架bookList即可
public class Show implements IOpera{
    @Override
    public void work(BookList bookList, String person) {
        System.out.println(bookList);
        System.out.println("展示成功");
    }
}
2.1.5 Borrow - 借书
  • 书只有一本,看有无被借走
    • 无权知晓谁就走的
public class Borrow implements IOpera{
    @Override
    public void work(BookList bookList, String person) {
        System.out.print("请输入你要借的书:>");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int index = Search.search(bookList, name);
        if(index != -1) {
            if(bookList.getBooks(index).isState()) {
                System.out.println(name + "已被借走");
            }else {
                System.out.println("借阅成功");
                bookList.getBooks(index).setState(true);
                bookList.getBooks(index).setBorrower(person);
            }
        }else {
            System.out.println("你要的书这里找不到");
        }
    }
}
2.1.6 Return - 还书
  • 归还的书应该是这书架的
    • 如果找不到这本书,那么就不是原书架的
    • 如果这本书没被借走,那么就不是原书架的
public class Return implements IOpera{
    @Override
    public void work(BookList bookList, String person) {
        System.out.print("请输入你要归还的书:>");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int index = Search.search(bookList, name);
        if(index != -1 && bookList.getBooks(index).isState()) {
            System.out.println("归还成功");
            bookList.getBooks(index).setState(false);
        }else {
            System.out.println("此书并不是你在此处借的");
        }
    }
}
2.1.7 Exit - 退出系统
  • 我取消了exit(0)退出的想法,因为我想继续有人进入系统
public class Exit implements IOpera{
    @Override
    public void work(BookList bookList, String person) {
        System.out.println("退出成功");
        //System.exit(0) 为正常退出执行!就是直接不执行了,而不是跳到末尾,也不是直接此方法结束,是整个程序结束
    }
}

3. Admin 管理员视角的menu()方法

知识背景:数组向上转型技巧 --> 各元素不同的向上转型

  • 这是管理员类
public class Admin extends User{
    public Admin(String name) {
        super(name);//传参不是给自己,而是给父类构造
    }
    //不同下标的元素,实现了不同的向上转型,重写了不同的方法
    private IOpera[] iOperas = {
            new Exit(),
            new Add(),
            new Del(),
            new Search(),
            new Show()
    };
}
    @Override
    public void menu(BookList bookList) {
        int choice = 0;
        do{
            
            System.out.println("********************************");
            System.out.println("hello " + 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.print("请输入你的选择:>");
            
            Scanner scanner = new Scanner(System.in);
            choice = scanner.nextInt();
            
            iOperas[choice].work(bookList, this.name);
            //调用被不同向上转型的不同引用的work()方法
        }while(!(iOperas[choice] instanceof  Exit));
        //只要改下标对应元素是Exit实例化的,就退出。
    }

4. Normal 普通用户视角的menu()方法

  • 同理:
public class Normal extends User{
    public Normal(String name) {
        super(name);
    }
    private IOpera[] iOperas = {
            new Exit(),
            new Search(),
            new Borrow(),
            new Return()
    };
    @Override
    public void menu(BookList bookList) {
        int choice = 0;
        do {
            System.out.println("********************************");
            System.out.println("hello " + name);
            System.out.println("** 1. 查阅图书 ");
            System.out.println("** 2. 借阅图书 ");
            System.out.println("** 3. 归还图书 ");
            System.out.println("** 0. 退出 ");
            System.out.println("********************************");
            System.out.print("请输入你的选择:>");
            Scanner scanner = new Scanner(System.in);
            choice = scanner.nextInt();
            iOperas[choice].work(bookList, this.name);
        }while(!(iOperas[choice] instanceof  Exit));
    }
}

测试

  • 一定要在main方法所在文件才能运行哦
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆

这是我的代码仓库!(在马拉圈的23.1里)代码仓库 图书管理代码具体位置

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

s:103

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

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

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

打赏作者

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

抵扣说明:

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

余额充值