Java基础小项目(图书系统小练习)

实现效果介绍

此小练习的实现效果如下:它将面对 管理员普通用户 两种用户来提供服务,并且各自的服务并不相同。下面让我们一起来实现代码吧

在这里插入图片描述

实现思路

一般写项目,每个独立的功能都会写成一个类,而有关联的功能,都会将多个类存放在一个包中,此项目我们将用 3 个包来体现我们的效果

1. book包

  1. 我们这个是图书系统小练习,必不可缺的就是Book类了 —> 用来定义一本书
  2. 既然是图书系统,那么必然不可能仅仅只有一本书,我们还需要一个书架,来存储书籍 BookList 类

2. user包

  1. 因为我们有两种用户可以使用这个图书系统,而且每种用户都有自己的特性,所以也需要定义成类
  2. 有 User类(后面两个类的共同特征抽取出来的,User类可以是一个抽象类),adminUser类,normalUser类

3. opertion包

这个包底下就是我们的基本操作了……

4. Main类

上面的类就已经实现了我们需要的功能了,Main类就是来整合这些操作功能的,在Main类中,我们需要根据登陆的账户类型不同,来显示不同的菜单供其使用图书系统.

具体代码实现

book包

Book类

这个Book类主要是存放一本书的具体信息,这个信息包括书名,作者,价格,类型,是否被借出。并且为了安全起见,我们需要吧这些信息全部都用private来修饰,然后对外提供一些公开的接口供外面的使用(这就体现了面向对象中的 封装

public class Book {
    private String name;  // 书名
    private String author;  // 作者
    private double price; // 价格
    private String type;  // 类型
    private boolean isBorrowed;  // 是否借出

    public Book(String name, String author, double 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 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 isBorrowed() {
        return isBorrowed;
    }

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

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

BookList类,这就相当于一个书架,用来存放书籍的,而且在其构造方法中,我们默认就放了三本书,在其里面也提供了对 usedSize 和 books 两个变量的公开操作方法

public class BookList {

    public int getBookLength() {
        return bookLength;
    }

    private int bookLength = 10;
    private Book[] books = new Book[bookLength];  // 数组用来存放书的,最多放10本书
    private int usedSize; // 数组中已存几本书

    /**
     * 默认书架上有三本书
     */
    public BookList() {
        books[0] = new Book("三国演义","罗贯中",56.7,"小说");
        books[1] = new Book("西游记","吴承恩",66.6,"小说");
        books[2] = new Book("红楼梦","曹雪芹",54.3,"小说");
        this.usedSize = 3;
    }

    /**
     * 获取已存几本书
     * @return
     */
    public int getUsedSize() {
        return usedSize;
    }

    /**
     * 增加/删除时,修改usedSize
     * @param usedSize
     */
    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }

    // 因为借书,新增,删除等操作,都是针对Book[] 书架来的,其实可以在这里实现,但为了低耦合,使用接口

    /**
     * 获取pos位置的书
     * @param pos
     * @return
     */
    public Book getPos(int pos) {
        if(pos < 0 && pos == bookLength) {
            throw new IndexNotValidException("pos不合法");
        }
        return books[pos];
    }

    /**
     * 给数组pos位置放一本书
     * @param pos
     * @param book
     */
    public void setBooks(int pos,Book book) {
        if(pos < 0 && pos == bookLength) {
            throw new IndexNotValidException("pos不合法");
        }
        books[pos] = book;
    }
}

operation包

在这个包里,我们用到了 接口,因为所有的操作中,都只有一个 work方法,而且参数也都一样,我们就可以将其抽象成一个接口,然后后面实现功能的时候,我们直接实现这个接口的内容即可

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

AddOperation
public class AddOperation implements IOPeration{
    public void work(BookList bookList) {
        int currentSize = bookList.getUsedSize();
        if(currentSize == bookList.getBookLength()) {
            throw new IndexNotValidException("书架已满");
        }

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入图书的名字:");
        String name = sc.nextLine();
        System.out.println("请输入图书的作者");
        String author = sc.nextLine();
        System.out.println("请输入图书的价格");
        Double price = sc.nextDouble();
        System.out.println("请输入图书的类型");
        String type = sc.nextLine();

        Book book = new Book(name,author,price,type);

        bookList.setBooks(currentSize,book);

        bookList.setUsedSize(currentSize+1);

        System.out.println("新增成功");
    }
}
BorrowOperation
public class BorrowOperation implements IOPeration {
    public void work(BookList bookList) {
        System.out.println("借阅图书");

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入借阅图书的名字:");
        String name = sc.nextLine();

        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            if(book.getName().equals(name)) {
                book.setBorrowed(true);
                System.out.println("借阅成功");
                return;
            }
        }

        System.out.println("此书已被借阅或这没有这本书");
    }
}
DeleteOperation
public class DeleteOperation implements IOPeration  {
    public void work(BookList bookList) {
        System.out.println("删除图书");

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入删除图书的名字:");
        String name = sc.nextLine();

        int index = 0;
        int currentSize = bookList.getUsedSize();
        int i = 0;
        for (; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            if(book.getName().equals(name)) {
                index = i;
                break;
            }
        }

        // 1. 没有找到  2.找到了
        if(i == currentSize) {
            System.out.println("没有你要删除的图书");
            return;
        }

        // 开始删除
        for (int j = index; j < currentSize - 1; j++) {
            Book book = bookList.getPos(j+1);
            bookList.setBooks(j,book);
        }

        bookList.setBooks(currentSize-1,null);
        bookList.setUsedSize(currentSize-1);

        System.out.println("删除成功");
    }
}
DisplayOperation
public class DisplayOperation implements IOPeration {
    public void work(BookList bookList) {
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            System.out.println(book);
        }
    }
}
ExitOperation
public class ExitOperation implements IOPeration {
    // 退出前可能需要销毁书架上的所有书
    public void work(BookList bookList) {
        System.out.println("退出系统");
        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            bookList.setBooks(i,null);
        }
        System.exit(0);
    }
}
FindOperation
public class FindOperation implements IOPeration {
    public void work(BookList bookList) {
        System.out.println("查找图书");

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入图书的名字:");
        String name = sc.nextLine();

        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            if(book.getName().equals(name)) {
                System.out.println("找到这本书,信息如下:");
                System.out.println(book);
                return;
            }
        }

        System.out.println("没有找到");
    }
}
ReturnOperation
public class FindOperation implements IOPeration {
    public void work(BookList bookList) {
        System.out.println("查找图书");

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入图书的名字:");
        String name = sc.nextLine();

        int currentSize = bookList.getUsedSize();
        for (int i = 0; i < currentSize; i++) {
            Book book = bookList.getPos(i);
            if(book.getName().equals(name)) {
                System.out.println("找到这本书,信息如下:");
                System.out.println(book);
                return;
            }
        }

        System.out.println("没有找到");
    }
}

User包

User类

这里定义了一个 IOPeration的数组(也就是operation中的接口创建的数组),一个很巧妙的用法:因为AdminUser 和 NormalUser 中的菜单并不相同,但是它们都实现了IOPeration接口,因此我们可以通过IOPeration数组来分别存储我们需要进行的操作

abstract public class User {
    // 防止其他包底下也要继承User,所以用protected
    protected String name;

    public IOPeration[] ioPerations;

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

    public abstract int menu();

    public void doOperation(int choice, BookList bookList) {
        ioPerations[choice].work(bookList);
   
NormalUser 与 AdminUser

在实例化用户之前,我们就在不同的类中创建了 IOPeration数组,并填入当前类所需要的对象了,然后根据我们的选择,返回了下标,然后在User类中的doOperation方法直接在数组中取出对应下标的对象,然后调用 work方法,来实现功能

public class NormaUser extends User {

    public NormaUser(String name) {
        super(name);
        this.ioPerations = new IOPeration[] {
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation(),
        };
    }

    @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("0. 退出系统");

        System.out.println("请输入你的操作:");
        Scanner sc = new Scanner(System.in);
        int choice = sc.nextInt();
        return choice;
    }
}
public class AdminUser extends User {

    public AdminUser(String name) {
        super(name);
        this.ioPerations = new IOPeration[] {
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DeleteOperation(),
                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 sc = new Scanner(System.in);
        int choice = sc.nextInt();
        return choice;
    }
}
Main方法

我们可以看到Main方法是相当简洁的,里面只有一个 login方法,而login方法的返回值是User,这样我们就可以发生 向上转型,从而实现多态

public class Main {
    public static User login() {
        System.out.println("请输入姓名:");
        Scanner sc = new Scanner(System.in);
        String name = sc.nextLine();
        System.out.println("请输入你的身份:1)管理员   0)普通用户");
        int choice = sc.nextInt();
        if(choice == 1) {
            return new AdminUser(name);
        } else {
            return new NormaUser(name);
        }
    }

    public static void main(String[] args) {
        BookList bookList = new BookList();
        User user = login();  // user到底引用那个对象,由login的返回值确定

        while(true) {
            int choice = user.menu();
//          根据下行代码来看,要不要doOperation方法都可,但是存在的话,代码更加的解耦合
//            user.ioPerations[choice].work(bookList);   
            user.doOperation(choice,bookList);
        }
    }
}

总结

框架的搭起:Book类 -> BookList类 -> operation包(先不要实现功能,框架起来后,功能实现就容易了) -> AdminUser+NormalUser类 + Main类
其中最难的地方当属:IOPeration数组了,只要这个地方理解了,相信整个项目对你来说,难度就不大了

这个图书管理系统,更主要的是我们要理解 框架如何一步步搭起来的,不要看这个项目小,它可是涵盖了许多 Java基础知识(数组,封装,继承,多态,抽象类,接口,异常……),刚开始写的时候,不要想一口吃成胖子,不可能一开始就会想到所有的功能,一步一步来。

对于Java基础语法不是很熟悉的话,可以看看博主的另一篇文章:Java类和对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值