需求分析
首先不管是设计什么,或者用什么语言,我们第一步都是进行需求分析,即使以后我们到了工作的
地方,也是先进行分析,然后分配任务,开始干活。
所以设计这个图书管理,我们先从使用者开始分析,对于使用者,分为管理员和用户
如下图所示
先创建一个包,然后包中分为admin类和customer类还有一个user类,其次是书,分为书和书架
如下图所示
也是跟一样,先创建一个包,然后分类。然后就是不同使用者能进行的操作。
如下图所示
创建一个包装这些类,让我们看看都有哪些类
如下图所示
这些是管理员能实现的功能
紧接着肯定是用户了
跟管理员不同的是新增图书以及删除图书
新增图书
下面是代码实现比较难的就是管理员的新增图书和删除图书
先看代码
package step;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class AddStep implements IoStep {
@Override
public void work(BookList bookList) {
System.out.println("新增图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入书名:->");
String name = scanner.nextLine();//nextLine可以读入空格
System.out.println("请输入作者:->");
String author = scanner.nextLine();
System.out.println("请输入类型:->");
String type = scanner.nextLine();
System.out.println("请输入价格:->");
int price = scanner.nextInt();//一般情况把整形放到最后
Book book = new Book(name, author, price, type);//添加书
int currentAmount = bookList.getAmount();
for (int i = 0; i < currentAmount; i++) {
Book book1 = bookList.getBooks(i);//book指向书架数组的第i个下标
if (book1.getName().equals(name)) {
System.out.println("已经有这本书了");
return;
}
}
if (currentAmount == bookList.getBooks().length) {//判断当前书的数量跟书架数组的长度也就是数量是不是一样多
System.out.println("书架已经满了");
} else {
bookList.setBooks(currentAmount, book);
bookList.setAmount(currentAmount + 1);//然后当前数量加1
}
}
}
从这行开始讲int currentAmount = bookList.getAmount();这行代码的实现是通过获取bookList的数量
然后赋值给变量currentAmount。紧着是这个for循环,第一步吗,先遍历数组,然后如果碰到跟
书名一样的时候,会输出已经有这本书了,紧接着return返回。
然后if语句用来判断当前书的数量跟书架数组的长度也就是数量是不是一样多,如果是的话,就说
明我们的书架已经满了,如果没有,就通过我们的bookList这个书架类的引用指向set方法根据你投
入的参数currentAmount和book来进行添加,最后再给你书架的数量加1。
删除图书
接着是删除的代码
package step;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class DeleteStep implements IoStep {
@Override
public void work(BookList bookList) {
System.out.println("删除图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入书名:->");
String name = scanner.nextLine();//nextLine可以读入空格
int currentAmount = bookList.getAmount();
int pos = 0;//存放要删除的那本书的下标
int i = 0;
for (; i < currentAmount; i++) {
Book book = bookList.getBooks(i);
if (book.getName().equals(name)) {
pos = i;//相等说明找到了
break;
}
}
if (i == currentAmount) {
System.out.println("没有这本书!");
return;
}
//开始删除
int j = pos;
for (; j < currentAmount - 1; j++) {//往前覆盖,下标要减一,不然数组会越界
//[j]=[j+1]为了覆盖掉要删除的那本书
Book book = bookList.getBooks(j + 1);//把 j+1 下标的存到 book
bookList.setBooks(j, book);//然后把 j+1 下标的 book 给到 j 下标的 book
}
bookList.setBooks(j, null);//把覆盖的j+1 下标设置成空
bookList.setAmount(currentAmount - 1);
System.out.println("删除成功");
}
}
也是一样我们从int pos = 0;开始讲,这句代码我在图中有注释,它的也是就是存放要删除的那本书
的下标。接着for循环遍历数组,也是一样,通过传入i然后遍历数组,如果名字一样说明找到了,
直接结束这个循环,然后来到下面这个if循环,如果i跟总数量相同,我们就输出没有这本书,然后
返回。最后一步来到开始删除,标记一下j也就是要删除的书的下标,然后为什么要j<总数量减1呢
我的注释也写的很清楚,为了不然数组越界,因为要用到覆盖的方法,然后通过书架get的方法得
到书的位置然后赋给book这个引用,接着再把j+1的下标对应的内容,给到book这个引用,然后再
把j+1的下标设置成null,最后再总数量减1。
完整代码
Book
package book;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 楠
* Date: 2024-02-05
* Time: 11:20
*/
public class Book {
private String name;
private String author;
private int price;
private String type;
private boolean borrow;//默认没借出,所以不用设置
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 String getAuthor() {
return author;
}
public int getPrice() {
return price;
}
public String getType() {
return type;
}
public void setName(String name) {
this.name = name;
}
public void setAuthor(String author) {
this.author = author;
}
public void setPrice(int price) {
this.price = price;
}
public void setType(String type) {
this.type = type;
}
public void setBorrow(boolean borrow) {
this.borrow = borrow;
}
public boolean isBorrow() {
return borrow;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\''
+ ", author='" + author + '\''
+ ", price=" + price + ", type='"
+ type + '\''
+ ","+ (borrow == true?"已借出" : "未借出")
+ '}';
}
}
BookList
package book;
public class BookList {
private Book[] books;//用到了组合,可以复用Book的属性和方法
private int amount;//记录书的数量,默认为0
public BookList() {
this.books = new Book[10];//初始化书
books[0] = new Book("三国演义", "罗贯中", 88, "小说");
books[1] = new Book("红楼梦", "曹雪芹", 66, "小说");
books[2] = new Book("水浒传", "施耐庵", 99, "小说");
System.out.println();
this.amount = 3;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public Book[] getBooks() {//返回了整个 Book 数组 books
return books;
}
public Book getBooks(int pos) {//获取的是该数组中特定索引的 Book 对象
return books[pos];
}
public void setBooks(int pos, Book book) {
books[pos] = book;//把books这个数组的位置设置成一本书
}
}
Borrow
package step;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowStep implements IoStep {
@Override
public void work(BookList bookList) {
System.out.println("借阅图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入书名:->");
String name = scanner.nextLine();//nextLine可以读入空格
int currentAmount = bookList.getAmount();
for (int i = 0; i < currentAmount; i++) {
Book book1 = bookList.getBooks(i);//book1指向书架数组的第i个下标,或者这么说通过传入i然后得书架数组把信息赋给book1
if (book1.getName().equals(name)) {
book1.setBorrow(true);
System.out.println("借阅成功!");
System.out.println(book1);
return;
}
}
System.out.println("你要借阅的书,不存在!");
}
}
Return
package step;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class ReturnStep implements IoStep {
@Override
public void work(BookList bookList) {
System.out.println("归还图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入书名:->");
String name = scanner.nextLine();//nextLine可以读入空格
int currentAmount = bookList.getAmount();
for (int i = 0; i < currentAmount; i++) {
Book book1 = bookList.getBooks(i);//book1指向书架数组的第i个下标,或者这么说通过传入i然后得书架数组把信息赋给book1
if (book1.getName().equals(name)) {
book1.setBorrow(false);
System.out.println("归还成功!");
System.out.println(book1);
return;
}
}
System.out.println("你要归还的书,不存在!");
}
}
Find
package step;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class FindStep implements IoStep {
@Override
public void work(BookList bookList) {
System.out.println("查阅图书");
System.out.println("请输入书名:->");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int currentAmount = bookList.getAmount();//获取当前书的数量
for (int i = 0; i < currentAmount; i++) {//遍历数组,打印书
Book book = bookList.getBooks(i);
if (book.getName().equals(name)) {//利用equals方法判断数组里的书名跟用户输入的书名一不一样
System.out.println(book);
}
}
}
}
Show
package step;
import book.Book;
import book.BookList;
public class ShowStep implements IoStep {
@Override
public void work(BookList bookList) {
System.out.println("显示图书");
int currentAmount = bookList.getAmount();//获取当前书的数量
for (int i = 0; i < currentAmount; i++) {//遍历数组,打印书
Book book = bookList.getBooks(i);//book指向书架数组的第i个下标
System.out.println(book);
}
}
}
Exit
package step;
import book.BookList;
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 楠
* Date: 2024-02-05
* Time: 11:29
*/
public class ExitStep implements IoStep {
@Override
public void work(BookList bookList) {
System.out.println("退出系统");
Scanner scanner = new Scanner(System.in);
System.exit(0);
}
}
Io接口
package step;
import book.BookList;
public interface IoStep {
void work(BookList bookList);
}
Admin
package user;
import step.*;
import java.util.Scanner;
public class Admin extends User {
public Admin(String name) {
super(name);
this.ioStep = new IoStep[]{new ExitStep(), new FindStep(), new AddStep(), new DeleteStep(), new ShowStep()};
//帮助user父类初始化IoStep数组,然后记住数组下标从0开始
}
@Override
public int menu() {
System.out.println("----------管理员用户----------");
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);
System.out.println(" 请输入你的选项:-> ");
int choice = scanner.nextInt();
return choice;
}
}
Customer
package user;
import step.*;
import java.util.Scanner;
public class Customer extends User {
public Customer(String name) {
super(name);
this.ioStep = new IoStep[]{new ExitStep(), new FindStep(), new BorrowStep(), new ReturnStep(), new ShowStep()};
//帮助user父类初始化IoStep数组,然后记住数组下标从0开始
}
@Override
public int menu() {
System.out.println("----------普通用户----------");
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);
System.out.println(" 请输入你的选项:-> ");
int choice = scanner.nextInt();
return choice;
}
}
User
package user;
import book.BookList;
import step.IoStep;
public abstract class User {
protected String name;
protected IoStep[] ioStep;//根据选择执行相对应的
public User(String name) {
this.name = name;
}
public abstract int menu();//抽象方法
public void doStep(int choice, BookList bookList) {
ioStep[choice].work(bookList);//选择身份后进入相对应的菜单后,根据用户的选择调用对应的方法
}
}
Main
import book.BookList;
import user.Admin;
import user.Customer;
import user.User;
import java.util.Scanner;
public class Main {
public static User login() {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你的姓名:");
String name = scanner.nextLine();
System.out.println("请输入你的身份:1->管理员 0-> 普通用户 ");
int choice = scanner.nextInt();
if (choice == 1) {
return new Admin(name);
} else {
return new Customer(name);
}
}
public static void main(String[] args) {
BookList bookList = new BookList();
User user = login();//向上转型,根据login方法返回的对象进行转型
while (true) {
int choice = user.menu();//动态绑定
user.doStep(choice, bookList);//根据choice的选择 来决定调用的是哪个方法
}
}
}
总结
接触到面向对象,不断的通过对象调用方法,感觉有点乱,但是慢慢熟练后就能掌握好,
一起进步!!!