java练习-图书管理系统

在本项目中,对业务的逻辑要求并不高,主要要求设计的架构,和知识的使用
在项目中:找对象—创建对象—使用对象
在图书管理系统中,有书和用户两个对象。
首先创建bookuser两个包。

在用户对象中,有普通用户和管理员。
首先创建User类,普通用户和管理员都有姓名,再创建AdminUserNormalUser, 这两个类继承User类。
将各种操作写道operation包中,定义IOperation操作接口,声明work函数,让各种功能都使用该接口,并重写work方法。

程序实现了退出操作ExitOperation、查询图书操作FindOperation、添加书籍操作AddOperation、删除书籍操作DelOperation、展示书籍操作DisplayOperation、借出书籍操作BorrowOperation、归还书籍操作ReturnOperation
其中AdminUser包含:退出操作、查询操作、添加书籍操作、删除书籍操作、展示书籍操作。
NormalUser包含:退出操作、查询操作、借出书籍操作、归还书籍操作。

User

public class User {
    protected String name;

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

再创建NormalUserAdminUser,让他继承User类。子类要先帮助父类构造
NormalUser

public class NormalUser extends User{

    public NormalUser(String name) {
        super(name);
    }
}

AdminUser

public class AdminUser extends User{
    public AdminUser(String name) {
        super(name);
    }
}

book包中,首先抽象出一个book类用来描述书,由private描述表现出来了封装性,同时要给属性提供构造方法,get和set方法
这里构造方法没有写isBorrowed,因为是否借出属性默认没有借出。不初始化

public 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;
    }

}

书创建好后,我们还需要一个书架用来存放书籍。创建BookList定义书架
创建一个数组,用来当书架。
默认书架只能放十本书
书架上本身存在三本书【也就是事先往书架中存三本书】写在构造方法中,调用这个类的构造方法时,就直接给books中放书。
按理,这里应该写一些操作数组的方法,但在这我们不这么做,我们把这些行为都写到接口当中

package book;

public class BookList {
    public Book[] books = new Book[10];  //默认书架只能放十本书
    public int usedSize;  //存储当前书的个数

    //事先通过构造方法,初始化的时候,给数组里预存三本书。
    public BookList() {
        //    书架上本身存在三本书
        books[0] = new Book("三国演义","罗贯中",89,"小说");
        books[1] = new Book("name2","author2",102,"type2");
        books[2] = new Book("name3","author3",103,"type3");
        this.usedSize = 3;
    }
    //按理,这里应该写一些操作数组的方法,但在这我们不这么做,我们把这些行为都写到接口当中

}

新建一个operation包,里面用来存放各种接口

package operation;
import book.BookList;

/**
 * @ClassName: AddOperation
 * @Description: TODO:添加图书
 */
public class AddOperation {

    public void work(BookList bookList) {
        //添加图书
    }
}
package operation;
import book.BookList;

/**
 * @ClassName: FindOperation
 * @Description: TODO:查找图书
 */
public class FindOperation {
    public void work(BookList bookList) {
        //查找图书
    }
}

在不同的操作中,我们都是使用work方法,传入参数BookList。
可以写成一个接口IOperation

package operation;
import book.BookList;

/**
 * @ClassName: IOperation
 */
public interface IOperation {
    void work(BookList bookList);
}

这样的话,直接让操作implements IOperation
现在看可能会觉得和之前没有接口的时候也没什么区别嘛。
但是当我们所有的操作都实现了这个接口,那么我们就可以很轻易地做到向上转型动态绑定多态

public class AddOperation implements IOperation{

    public void work(BookList bookList) {
        //添加图书
    }
}
public class FindOperation implements IOperation{
    public void work(BookList bookList) {
        //查找图书
    }
}

用同样的方法创建删除图书DelOperation,展示图书DisplayOperation,退出系统ExitOperation,归还图书ReturnOperation,借阅图书BorrowOperation
结构如下:
在这里插入图片描述
接下来,整合程序,让他能够跑起来。

第0步:准备数据
初始化new 一个bookList ,BookList 中的构造函数中初始化了三本书,数据准备完成。

BookList bookList = new BookList();

第1步:登录
在login()函数中,由于选择不同,返回的对象也不同。这个对象可能是admin也可能是normal。
因此这里的返回值写成User类型,利用了向上转型,来确定此时返回的到底是什么对象。

    //返回User
    //利用了向上转型,来确定此时返回的到底是什么对象。
    public static User login() {
        System.out.println("please input your name");
        Scanner scanner = new Scanner(System.in);
        String userName = scanner.nextLine();
        System.out.println("please input your id: 1->admin, 0->user");
        int choice = scanner.nextInt();
        //当引用的对象不一样时,打印的菜单也不一样。将不同的菜单分别写道AdminUser类和NormalUser类中。
        if (choice == 1) {
            //Admin
            return new AdminUser(userName);
        } else {
            //User
            return new NormalUser(userName);
        }
    }
    
    public static void main(String[] args) {
        BookList bookList = new BookList();
        User user = login();
        }

在这里无法调用menu,因为在这里是用父类User调用,父类引用只能调用自己的方法;user中没有menu,因此在user中加上menu。user中的方法menu没有具体的执行,实际就是一个抽象方法,User类也是一个抽象类

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

当引用的对象不一样时,打印的菜单也不一样。将不同的菜单分别写道AdminUser类和NormalUser类中。
通过这个user去调用menu。他引用谁,调用的就是谁的menu()。调用的是谁的菜单,在这里choice选择的就是谁的数字。

【在这里,怎么去根据choice确定调用的是那个方法?】
让每个对象,把自己对应的操作存到数组中,
在user抽象类中,定义数组 protected IOperation[] iOperations;

    protected IOperation[] iOperations;

此时只定义数组,但没初始化,内存都没分配,因为不知道要存储几个操作。
在admin和normal中分别初始化操作数组,放在构造函数中,使其在new对象时直接初始化完成

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 class NormalUser extends User{
    public NormalUser(String name) {
        super(name);

        this.iOperations = new IOperation[] {
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }
}

数组定义好后,现在需要写一个操作接口数组的方法,使其引用admin和normal时都可以调用。所以把这个方法写道user中

    //根据选择,调用booklist里面数组的某个下标
    public void doOperation(int choice, BookList bookList) {
        //iOperations[choice]相当于拿到了一个对象【iOperations数组的一个元素】
        //调用这个对象的work方法并传入bookList
        iOperations[choice].work(bookList);
    }
    public static void main(String[] args) {
        //0. 准备数据
        BookList bookList = new BookList();
        //1. 登录
        User user = login();
        int choice = user.menu();
        user.doOperation(choice, bookList);  //使用接口数组
    }

各个功能的实现:

AddOperation

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class AddOperation implements IOperation{

    public void work(BookList bookList) {
        //添加图书
        System.out.println("add book");
        System.out.println();
        System.out.println("please input add book name");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();

        System.out.println("please input add book author");
        String author = scanner.nextLine();

        System.out.println("please input add book price");
        int price = scanner.nextInt();
        scanner.nextLine();  //把回车读进去
        //nextInt和nextLine 要先输入nextLine,否则输入nextInt后的回车会被nextLine读进去
        //如果必须先输入nextLine,就在nextLine后面把回车读进去 scanner.nextLine();

        System.out.println("please input add book type");
        String type = scanner.nextLine();

        Book book = new Book(name, author, price, type);   //得到了一本书

        //1. 获取当前可以存放书的位置
        int currentSize = bookList.getUsedSize();
        //2. 把书放入指定位置
        bookList.setBooks(book,currentSize);
        //3. 书的有效个数+1
        bookList.setUsedSize(currentSize + 1);
        System.out.println("aa");
    }
}

BorrowOperation

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class BorrowOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        //借阅书籍
        System.out.println("borrowed book");
        System.out.println("please input book you want to borrowed");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            if (name.equals(book.getName())) {
                if (book.isBorrowed()) {
                    System.out.println("this book already borrowed");
                } else {
                    book.setBorrowed(true);
                    System.out.println("borrow success");
                }
                return;
            }
        }
        System.out.println("not found borrow book");
    }
}

DelOperation

package operation;

import book.Book;
import book.BookList;
import java.util.Scanner;

public class DelOperation implements IOperation{

    @Override
    public void work(BookList bookList) {
        //删除图书
        System.out.println("delete book");
        System.out.println("please input want delete book name");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        //遍历数组当中,是否有你要删除的书,如果有,记录下标
        int index = -1;
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            if (name.equals(book.getName())) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            System.out.println("not found");
            return;
        }
        for (int i = index; i < currentSize - 1; i++) {
            Book book = bookList.getPos(i + 1);
            bookList.setBooks(book, i);     //将i+1的book放到i下
        }
        //在Java中,只有没人引用的对象,才会回收
        bookList.setBooks(null, currentSize - 1);   //每次删除都要置为空
        bookList.setUsedSize(currentSize - 1);   //存放发currentSize - 1
        System.out.println("delete success !");
    }
}

DisplayOperation

package operation;

import book.Book;
import book.BookList;

public class DisplayOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        //显示所有图书
        System.out.println("display book");
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            System.out.println(book);
        }
    }
}

ExitOperation

package operation;
import book.BookList;

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

FindOperation

package operation;

import book.Book;
import book.BookList;
import java.util.Scanner;

public class FindOperation implements IOperation{
    public void work(BookList bookList) {
        //查找图书
        System.out.println("find book");
        System.out.println("please input book name");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            if (name.equals(book.getName())) {
                System.out.println("---find it ---");
                System.out.println(book);
                return;
            }
        }
        System.out.println("---not found---");
    }
}

ReturnOperation

package operation;

import book.Book;
import book.BookList;
import java.util.Scanner;

public class ReturnOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        //归还图书
        System.out.println("return book");
        System.out.println("please input book name you want to return");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            if (name.equals(book.getName())) {
                if (book.isBorrowed()) {
                    book.setBorrowed(false);
                    System.out.println("return book success");
                    return;
                } else {
                    System.out.println("this book is not borrowed");
                    return;
                }
            }
        }
        System.out.println("not found book to return ");
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值