Java--图书管理系统(简易版)

发布于:2025-05-12 ⋅ 阅读:(18) ⋅ 点赞:(0)

目录

目录

前言

🔔1.library包

1.1 Book类

1.2 BookList类

🔔2.user包

2.1User类(父类)

2.2Admin(管理员)

2.3 NormalUser(普通用户)

🔔3.Operation包

🕐3.1 IOperation接口

🕑3.2ListOperation(查看操作)

🕒3.3AddOperation(增加操作)

🕓3.4BorrowOperation(借书操作)

🕔3.5ReturnOperation(还书操作)

🕕3.6DelOperation(删除操作)

🕖3.7FindOperation(查找操作) 

🕗3.8ExitOperation(退出操作)

🔔4.Main类

🔔5.效果展示


(ps:✨在本篇文章中我们介绍了图书管理系统📖,但是功能很少,所以在下一篇文章中,我又增加了几个功能:大家可以点击链接移步到下一篇文章(无讲解的)

https://blog.csdn.net/2401_84024092/article/details/147874135?fromshare=blogdetail&sharetype=blogdetail&sharerId=147874135&sharerefer=PC&sharesource=2401_84024092&sharefrom=from_link

前言

🌈本篇文章会实现一个控制台版本的“图书管理系统”,涉及到 JavaSE中的继承,多态,抽象类,接口。(代码部分附有详细的讲解✨)

在这个系统中:

1.能够表示多本图书的信息📘

2.提供两种用户:管理员普通用户

3.普通用户可以查看书籍列表查找图书📖,借书,还书

4.管理员可以查看书籍列表,查找图书📖,新增图书,删除图书

整体框架如下:🎉

程序目录如下:🎉

🔔1.library包

1.1 Book类

👉每本书📕都被定义为一个类,其中包含书名、作者、类型、价格和借阅状态等属性。这些属性均被设置为private访问权限,并通过getter和setter方法进行访问和修改。在类的构造方法中,我们会对这些属性进行初始化,其中借阅状态默认设置为未借出(false)。

package library;
//一本书
public class Book {//现实世界的书
    private String name;
    private String author;
    private String type;
    private double price;
    private boolean isBorrowed;
    public Book(String name, String author, String type, double price){
        this.name=name;
        this.author=author;
        this.type=type;
        this.price=price;
        this.isBorrowed=false;
    }
    //alt+ins自动生成
//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 String getType() {
        return type;
    }

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

    public double getPrice() {
        return price;
    }

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

    public boolean isBorrowed() {
        return isBorrowed;
    }

    public void setBorrowed(boolean borrowed) {
        isBorrowed = borrowed;
    }

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

1.2 BookList类

👉用来管理多个书籍对象

首先定义一个Book类类型的数组books,共分配1024个空间

✨注意:我们约定好,所有有效的书籍,都是从0开始连续递增排列的,以便可以通过size来描述有效书籍数目

package library;

public class BookList {
    private Book[] books=new Book[1024];//此数组中每个类型都是Book类类型
    //长度不方便灵活调整,预先创造大空间
    //把booklist想象为一个书架,书架总共有1024个位置,不能修改大小,所以设置为private
    //长度不方便灵活调整,预先创造大空间
    private int size =0;//有效元素
    public BookList(){
        books[0]=new Book("西游记","吴承恩","古典小说",100);//books[0]中存放的是一组实例对象
        books[1]=new Book("红楼梦","曹雪芹","古典小说",90);
        books[2]=new Book("高等数学","高斯","数学",40);
        books[3]=new Book("Java入门","詹姆斯高斯林","计算机",70);
        books[4]=new Book("红楼梦","曹雪芹","古典小说",90);
        size=5;
    }

    public Book getBook(int index) {//得到序号为index的书籍
        return books[index];//不会越界,因为此时还没满
    }

    public void setBook(int index,Book book) {
        books[index] = book;
    }//将序号index处设置为××书

    public int getSize() {
        return size;//有效书籍数量
    }

    public void setSize(int size) {
        this.size = size;//设置有效书籍数量
    }
}

🔔2.user包

两种用户:普通用户🙎‍♀️+管理员👩‍🏫

✨注意:普通用户与管理员的操作即存在重复的部分,也存在不同的部分,因此可以通过继承,把相同的部分通过父类(User)提取出来

2.1User类(父类)

将抽象菜单方法(menu)定义在父类中,供子类重写实现,并通过 IOperation[] 数组存储管理员和用户可执行的功能操作。

package library.user;

import library.BookList;
import library.IOperation;

public abstract class User {
    //不同 的用户不同的操作
    protected String name;//各个子类都有的内容,直接放在父类中
    //protected子类可以直接获取到,不必再去用getter setter
    protected IOperation[] operations;
    //当前这个类能进行那些操作,就往这个数组里添加对应的对象
    public User(String name){
        this.name=name;
    }
    public abstract int menu();//不知道父类的菜单(父类就没有菜单),我知道的只有管理员和用户的菜单
    // 所以使用abstract,子类再进行重写
    //为了避免父类被不小心创建出实例,所以要抽象(因为不能出现“父类菜单”)
    public void work(int choice, BookList bookList){//3.进入到父类的work方法
        if(choice<0||choice>=operations.length){
            System.out.println("输入的选项非法");
            return;
        }
        operations[choice].work(bookList);//4.调用我选择的方法里面的work方法,就能用此方法对booklist进行操作了
    }
}

2.2Admin(管理员)

🔔管理员应继承父类User,通过重写父类的 menu 方法,实现了自定义菜单功能,用户可通过输入选择进入相应功能模块。在子类构造函数中,首先调用父类构造方法完成名称初始化,随后对用户操作进行配置(包括退出,查看,查找、新增、删除的功能)。

注意:IOperation[]中的顺序已经和菜单中的选项对应了

package library.user;

import library.IOperation;
import library.Operation.*;

import java.util.Scanner;

public class Admin extends User{
    //private IOperation[] operations;//存放管理员的方法,这是什么类型呢,接口类型
    public Admin(String name) {
        super(name);
        operations=new IOperation[]{

         new ExitOperation(),
         new ListOperation(),
         new FindOperation(),
         new AddOperation(),
         new DelOperation(),

        };
    }

    @Override
    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 scanner=new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
}

2.3 NormalUser(普通用户)

🔔普通用户应继承父类User,通过重写父类的 menu 方法,实现了自定义菜单功能,用户可通过输入选择进入相应功能模块。在子类构造函数中,首先调用父类构造方法完成名称初始化,随后对用户操作进行配置(包括退出,查看,查找、借书、还书的功能)。

package library.user;

import library.Operation.IOperation;
import library.Operation.*;

import java.util.Scanner;

public class NormalUser extends User {
    //private IOperation[] operations;
    public NormalUser(String name) {
        super(name);
        //对所要的方法进行初始化
        operations = new IOperation[]{//普通用户进行的操作

                new ExitOperation(),//这是一个数组,此处下标为0
                new ListOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation(),
        };
    }

    @Override
    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 scanner=new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;

    }
}

🔔3.Operation包

👓此包中包括所有需要进行的操作类

🔔🔔🔔看到这里我们发现,书籍和用户并没有建立起联系,那么如何将BookList与用户实现“交互”呢?

通过IOperation接口把用户和书给关联起来

🕐3.1 IOperation接口

增加这个接口后,所有的操作类都要实现自IOperation接口,并重写其中的work方法,在每个操作类中的work方法的具体实现各不相同

✨注意:这里有人可能会问:如果不设置接口,只在每个类中都写上work方法,将参数BookList作为参数传递进去不就可以进行书籍与操作的联系吗,为什么还要设置接口呢

原因:简单来说就是限制代码的灵活性

解释:理论上是可行的,但是不加接口的话,无法保证所有的类都提供了work方法,也没法保证work方法的参数都是相同的。而加上后就能强制统一,方便后续的调用,否则如果大家提供的方法各不相同,就会显得很乱。

package library.Operation;

import library.BookList;

public interface IOperation {
   //也可以使用抽象类,但是我这个接口我只想保存一些方法,并没有什么实例属性要继承的
   //并且不能多继承
   //而User中的类是抽象性,因为我们需要继承name的属性
   void work(BookList bookList);
}

🕑3.2ListOperation(查看操作)

✨在每一次循环中都会创建一次book对象

✨接着调用booklist中的getBook方法获取到第i本书

当i为0时,创建的对象就是

Book book = new Book("西游记","吴承恩","古典小说",100);

最后实现打印操作,当打印book时,会自动调用Book类中的toString方法(打印格式可以自行调整)

package library.Operation;

import library.Book;
import library.BookList;

public class ListOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("查看书籍列表");
        for(int i=0;i<bookList.getSize();i++){
            Book book = bookList.getBook(i);//拿到第i本书
            System.out.println("["+i+"]"+book);
        }
    }
}

🕒3.3AddOperation(增加操作)

让用户输入新的书籍📕的信息,然后把这个新的书放到BookList

这本新书存放到数组的最后一个位置上,在BookList中已经存在N本书了(size),这些书对应的下标[0,N-1],新的图书📕就放到N的位置即可,在相应位置传入书后,有效元素size也要加一

package library.Operation;

import library.Book;
import library.BookList;

import java.util.Scanner;

public class AddOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("新增图书");
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入书名:");
        String name = scanner.next();
        System.out.println("请输入作者:");
        String author =scanner.next();
        System.out.println("请输入价格");
        double price = scanner.nextDouble();
        System.out.println("请输入类别");
        String type=scanner.next();
        Book book =new Book(name,author,type,price);
        int size=bookList.getSize();
        bookList.setBook(size,book);//传入book就相当于传入引用的空间
        bookList.setSize(size+1);//不能忘了修改size
        System.out.println("新增图书完成!");
    }
}

🕓3.4BorrowOperation(借书操作)

✨在借书操作时,要注意判断是否被借出

package library.Operation;

import library.Book;
import library.BookList;

import java.util.Scanner;

public class BorrowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("借书");
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入要借阅的图书编号:");
        int id= scanner.nextInt();
        if(id<0||id>=bookList.getSize()){
            System.out.println("输入错误");
            return;
        }
        Book book=bookList.getBook(id);//获取第id本书对象
        if(book.isBorrowed()){//先判断一下是否被借出
            System.out.println("该书已经被借出了");//如果真就被借出了
            return;
        }
        book.setBorrowed(true);//没借出我就可以借了
        System.out.println("借书成功!");
    }
}

🕔3.5ReturnOperation(还书操作)

✨在借书操作时,也要注意判断书是否已经被归还了

package library.Operation;

import library.Book;
import library.BookList;

import java.util.Scanner;

public class ReturnOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("还书");
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入要归还的图书编号:");
        int id= scanner.nextInt();
        if(id<0||id>=bookList.getSize()){
            System.out.println("输入错误");
            return;
        }
        Book book=bookList.getBook(id);
        if(!book.isBorrowed()){//先判断一下是否被借出false
            System.out.println("该书没借出,不能归还");//如果没被借出了,就不能换
            return;
        }
        book.setBorrowed(false);
        System.out.println("还书成功!");
    }
}

🕕3.6DelOperation(删除操作)

✨在进行删除操作时,如果是最后一本书📕,直接将有效元素size-1即可

如果是中间位置元素,可以把最后一本书📕放在待删除元素的位置上,然后再size-1即可。

package library.Operation;

import library.Book;
import library.BookList;

import java.util.Scanner;

public class DelOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("删除书籍");
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入要删除书籍的序号:");
        int index=scanner.nextInt();
        if(index<0||index>=bookList.getSize()) {
            System.out.println("序号超出范围");
            return;
        }
        if(index == bookList.getSize()-1){
            bookList.setSize(bookList.getSize()-1);//如果是最后一本书,直接将有效元素设置为size-1即可
        }else{//如果删除中间元素,就可以把最后一个元素,复制到待删除元素的位置上,然后size-1即可
            Book lastBook = bookList.getBook(bookList.getSize()-1);//先获取到最后一本书
            bookList.setBook(index,lastBook);
            bookList.setSize(bookList.getSize()-1);
        }
        System.out.println("删除书籍完成!");
    }
}

🕖3.7FindOperation(查找操作) 

✨查找操作只需验证输入内容与书籍列表中的条目是否一致。

package library.Operation;

import library.Book;
import library.BookList;

import java.util.Scanner;

public class FindOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("查找操作");
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入查找的书名");
        String name =scanner.next();
        for(int i=0;i<bookList.getSize();i++){
            Book book = bookList.getBook(i);
            if(book.getName().equals(name)){//比较字符串用这个
                System.out.println(book);
            }
        }
        System.out.println("查找完毕");
    }
}

🕗3.8ExitOperation(退出操作)

package library.Operation;

import library.BookList;

public class ExitOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("goodbye!");
        System.exit(0);//退出整个程序
    }
}

🔔4.Main类

✨在主类中根据用户输入跳转到具体的用户

package library;

import library.user.NormalUser;
import library.user.User;
import library.user.Admin;
import java.util.Scanner;
public class Main {
    private static User login(){
        System.out.println("请输入您的姓名:");
        Scanner scanner =new Scanner(System.in);
        String name = scanner.next();
        System.out.println("请输入您的角色(1.普通用户2.管理员)");
        int role = scanner.nextInt();
        if (role==1){
           return new NormalUser(name);
        }else if(role==2){
            return new Admin(name);
        }else{
            System.out.println("输入的角色有误");
            return null;
        }
    }
    public static void main(String[] args) {
        //书记管理
        library.BookList booklist=new BookList();
        //管理员和普通用户让用户选择
        User user = login();
        //User user=new NormalUser(name)
        //User user=new Admin(name)
        //向上转型
        while(true){
            int choice = user.menu();//多态
            user.work(choice,booklist);//将选择的菜单与书籍列表传入,假如是查找,普通用户
        }
    }
}

🔔5.效果展示


网站公告

今日签到

点亮在社区的每一天
去签到