代码实现—图书管理系统

目录

1、前言

2、逻辑

2.1 效果预览

2.2 逻辑框图

2.3 相关包展示

3、book包

3.1 Book类

3.2 Booklist类

4、operation包 

4.1 IOperation接口

4.2 AddOperation

4.3 BorrowOperatio

4.4 ReturnOperation

4.5 DelOperation

 4.6 DisplayOperation

4.7 ExitOperation

4.8 FindOperation 

5、user包

5.1 User

5.2 NormalUser

5.3  AdminUser

6、Main类


1、前言

本次我分享一篇最近自己研究的一个图书管理系统的代码,会将前面“类与对象”,“抽象类接口”,“继承与多态”相关内容串联起来,让大家理解的更加深刻,注意:此次代码我们只注重代码逻辑和相关的对象的协同,不注重业务逻辑,业务逻辑只是简单的实现功能即可。

2、逻辑

2.1 效果预览

2.2 逻辑框图

2.3 相关包展示

其中包括:

  • 存储书信息的book包,存储书操作的operation包,存储用户信息的user包,以及整合所有信息的Main类。

3、book包

3.1 Book类

  1. 我们定义book类,来存放一本书的所有数据,包括姓名、作者、价格、类型、是否被借出等成员;
  2. 我们给出了这些成员变量的构造方法;
  3. 因为这些成员是private修饰的,所以我们给出get和set方法来供外部类去调用;
  4. isBorrowed不用设置构造方法,因为默认是false的,我们在toString里面,把这部分改成已借出或者未借出即可,这里用到了三目操作符。
ublic class Book {
    private String name;
    private String author;
    private int price;
    private String type;
    private boolean isBorrowed;

    public Book(String name, String author, int price, String type) {
        this.name = name;
        this.author = author;
        this.price = price;
        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 getPrice() {
        return price;
    }

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

    public String getType() {
        return type;
    }

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

    public boolean isBorrowed() {
        return isBorrowed;
    }

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

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

3.2 Booklist类

  1. 定义Booklist类,相当于书架一样,里面可以找到书或者放置书;
  2. 提供Booklist的构造方法,目的是:当实例化Booklist的时候(在Main类下main方法中进行实例化),这里面就有三本书了;
  3. 分别提供获取到书的方法,和放置图书到数组中哪个位置的方法,pos就是数组下标;
  4. 提供获取当前书的个数和改变当前书的个数的方法;
public class BookList {
    private Book[] books = new Book[10];

    private int usedSize;//实时记录当前书还有多少本

    //初始书架中就有三本书,提供BookList的构造方法:
    public BookList(){
        books[0] = new Book("三国演义","罗贯中",19,"小说");
        books[1] = new Book("西游记","吴承恩",29,"小说");
        books[2] = new Book("红楼梦","曹雪芹",9,"小说");
        usedSize = 3;

    }

    //提供get方法,可以找到书架中的书,返回书的类型,pos是数组的下标
    public Book getBook(int pos){
        return books[pos];
    }
    //放置一本书
    public void setBook(int pos, Book book){
        books[pos] =book;
    }

    //获取当前书的本数
    public int getUsedSize() {
        return usedSize;
    }
    //实时修改当前书的个数
    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }
}

4、operation包 

4.1 IOperation接口

  1. IOperation中把对书架的操作,抽象出来,定义成接口因为所有的操作都是操作books这个数组,也就是操作书架,抽象出来形成接口即可。 
  2. 写一个抽象的方法,传入Booklist的对象即可。
public interface IOperation {
    void work(BookList bookList);
}

4.2 AddOperation

  1. 实现添加书到书架中的操作,其中需要用户自己输入图书的名字、作者、类型、价格等信息。
  2. 利用booklist中的setBook方法来放置这本新增的书;
  3. 最后要将当前的书的本数+1,所以调用setUsedSize方法即可。
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.nextLine();
        System.out.println("请输入图书的作者:");
        String author = scanner.nextLine();
        System.out.println("请输入图书的类型:");
        String type = scanner.nextLine();
        System.out.println("请输入图书的价格:");
        int price = scanner.nextInt();

        int currentSize = bookList.getUsedSize();//获取当前的书的本数
        Book book = new Book(name,author,price,type);
        bookList.setBook(currentSize,book);
        bookList.setUsedSize(currentSize+1);
        System.out.println("新增书籍成功!");

    }
}

4.3 BorrowOperatio

  1. 实现借出一本书的操作
  2. 要遍历当前书架上的书,用书名来做匹配;
  3. 如果找到了这本书,那么将book中的isBorrowed的成员通过setBorrowed方法改成true,即完成了借书的操作。
public class BorrowOperatio implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书!");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入借阅图书的名字:");
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            if(name.equals(book.getName())){
                book.setBorrowed(true);
                System.out.println("借阅成功!");
                break;
            }
        }

    }
}

4.4 ReturnOperation

  1.  实现归还图书的功能
  2. 实现方式和借出一本书相同,这里不在赘述了。
public class ReturnOperation implements  IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书!");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入借阅图书的名字:");
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            if(name.equals(book.getName())){
                book.setBorrowed(false);
                System.out.println("归还成功!");
                break;
            }
        }
    }
}

4.5 DelOperation

    1、采用的是先找到图书的位置i,将i的值赋给j,每次把j+1位置的图书给放到j的位置(getbook是把j+1位置的书放到book中,再用setBook把书放在数组中的j位置处即可),循环currentSize-1次,因为有j+1怕数组越界

    2、删除完了一本书,当前书的本书currentSize要--,并且要把新的书的本书传入到setUsedSzie中去。

    3、当break没有执行,最终i会加到currentSize的位置,这时候就可以判断为没有找到此书了。

public class DelOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书!");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入删除图书的名字:");
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        int i = 0;
        for ( i = 0; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            if(name.equals(book.getName())){
                for (int j = i; j <currentSize-1 ; j++) {
                    book = bookList.getBook(j+1);
                    bookList.setBook(j,book);
                }
                currentSize--;
                bookList.setUsedSize(currentSize);
                System.out.println("删除成功");
                break;
            }
        }
        if(i == currentSize){
            System.out.println("没有此书");
            return;
        }
    }
}

 4.6 DisplayOperation

  1. 实现显示图书的功能;
  2. 其实就是遍历这个书架,通过getBook()方法来获取图书并且打印出来即可。
public class DisplayOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            System.out.println(book);
        }
    }
}

4.7 ExitOperation

  1.  相当于C中的return 0,表示程序正常退出;
public class ExitOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统");
        System.exit(0);
    }
}

4.8 FindOperation 

  1. 实现寻找一本图书的功能;
  2. 遍历整个数组,用名字来匹配;
  3. currentSize变量获取到当前的书的个数,通过getUsedSize这个方法,直接获取因为是private修饰的,获取不到,只能用提供的get方法,这样会减少循环次数。 

  4. equals这里调用的是String方法的equals,不用重写。

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.nextLine();
        int currentSize = bookList.getUsedSize();
        int i =0;
        for (i = 0; i < currentSize; i++) {
            Book book = bookList.getBook(i);
            if(book.getName().equals(name)){
                System.out.println("找到了这本书!");
                System.out.println(book);
                //break;
            }
        }
        if(i == currentSize){
            System.out.println("没有你要找的这本书!");
        }

    }

}

5、user包

5.1 User

1、User作为父类,里面存储了子类(普通用户和管理员用户)的共性,包括一个抽象类方法menu,是方便main函数中调用user的时候,可以调用到menu这个方法,所以在User中声明这个menu方法。

2、定义一个接口类型的数组iOperations,目的是让子类能有属于自己的操作书架的方法。

3、this.iOperations 是管理员或者普通用户的那个接口数组(这个是从main方法中login选择的),choice是menu这个方法中我们选择并返回的,对应数组中的某个操作,调用的就是这个类的work方法(结合Main类来分析即可)

4、如果调用的是普通用户的this.iOperations[2].work(bookList),那么访问到的就是Borrow这个类。再访问到这个Borrow类中的work方法。 (结合NormalUser类以及BorrowOperation类来分析即可)

public abstract class User {
    protected String name;
    public abstract int menu();
    protected IOperation[] iOperations;

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

5.2 NormalUser

1、实现普通用户的对书架的相关操作;

2、为父类中定义的接口数组来创建对象,在数组中存储普通用户的相关书架的操作;

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

    @Override
    public int menu() {
        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;
    }
}

5.3  AdminUser

1、实现管理员用户的对书架的相关操作;

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(),

        };
    }

    //重写父类的抽象方法menu
    @Override
    public int menu() {
        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;
    }
}

6、Main类

1、login的返回值给到user,这时候就发生了整形提升,这时候普通用户或者是管理员用户已经新建完成了,里面的初始化(包括iOperation数组),和menu菜单都已经建立完成,调用user.menu的时候,发生了动态绑定,user现在是谁,那就是谁的menu。 

2、user.menu函数返回的是你选择菜单的数字,给到doOperation方法中。 

public class Main {

    //返回是管理员用户还是普通用户
    //用static修饰的,否则main里面不能直接调用
    public static User login(){
        //先输入管理员和普通用户的姓名
        System.out.println("请输入你的姓名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();


        System.out.println("请输入你的身份:1:-》管理员,0-》普通用户");
        Scanner scanner1 = new Scanner(System.in);
        int choice = scanner1.nextInt();
        if(choice == 1){
            //name在这里用到
            return new AdminUser(name);
        }
        else{
            return new NormalUser(name);
        }
    }

    public static void main(String[] args) {
        BookList bookList = new BookList();
        //Main main = new Main();
        User user = login();
        while(true){
            int choice = user.menu();//发生向上整形。
            user.doOperation(choice ,bookList);
        }

    }

猜你喜欢

转载自blog.csdn.net/weixin_44580000/article/details/124986220