找往期文章包括但不限于本期文章中不懂的知识点:
个人主页:我要学编程(ಥ_ಥ)-CSDN博客
所属专栏:JavaSE
顺序表的学习,点我
目录
图书管理系统菜单
基本框架:
书:
书架:
用户:
实现基本功能
新增图书:
借阅图书:
删除图书:
退出系统:
查找图书:
归还图书:
显示图书:
图书管理系统菜单
上面是根据选择不同用户,从而弹出的不同菜单。
基本框架:
先把大的框架搭建出来。这里我们要用到三个对象:书、书架、用户。
书:
一些基本属性:
public class Book { private String name; // 书名 private String author; // 作者 private int price; // 价格 private String type; // 类型 private int count; // 数量 private int lentCount; // 被借出的数量 }
用到private是为了防止所有人都可以拿到这些属性并且修改。
构造方法:
public Book(String name, String author, int price, String type, int count) { // 书一直在图书馆中,只有当新增或者删除才变动。而新增的书并不会一下子就被借出 // 因此不需要初始化被借出的数量 this.name = name; this.author = author; this.price = price; this.type = type; this.count = count; }
构造方法是为了在创建一个书的实例(新增)时初始化书的。
getter 、setter 方法:
// 下面这些方法是用来修改书的状态的 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 int getCount() { return count; } public void setCount(int count) { this.count = count; } public int getLentCount() { return lentCount; } public void setLentCount(int lentCount) { this.lentCount = lentCount; }
通过getter、setter方法来访问和修改书的属性。
重写toString 方法:
// 重写toString方法,以便于更好的打印 @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", author='" + author + '\'' + ", price=" + price + ", type='" + type + '\'' + ", count=" + count + ", lentCount=" + lentCount + '}'; }
我们后面在查找和显示书时,要把书的全部信息给都给打印出来,因此得重写toString 方法。
书架:
属性:
public class BookList { // 书架里面原本应该有书才对 // 书架是用来存放和管理书籍的,可以用顺序表(数组)来写 private Book[] books = new Book[10]; // 为了方便,只放了3本书 private int usedSize; // 书架已经使用的长度 }
getter、setter 方法:
public Book[] getBooks() { return books; } public void setBooks(Book[] books) { this.books = books; } public int getUsedSize() { return usedSize; } public void setUsedSize(int usedSize) { this.usedSize = usedSize; }
构造方法:
// 初始化3本书 public void func() { this.books[0] = new Book("Head First Java", "Kathy Sierra 、 Bert Bates", 79, "计算机", 100); this.books[1] = new Book("Java 核心技术 卷I", "Cay S. Horstmann", 119, "计算机", 100); this.books[2] = new Book("大话数据结构", "程杰", 59, "计算机", 100); this.usedSize = 3; } public BookList() { this.func(); }
构造方法用来初始化书架的,也就是创建书的实例放到书架上。
用户:
public abstract class User{ protected String name; // 因为这个name其子类也得使用 public User(String name) { this.name = name; }
因为用户有两种,所以User肯定不能知道是哪一种。因此就用抽象类来写。
普通用户:
public class RegularUsers extends User{ public RegularUsers(String name) { super(name); } }
管理员用户:
public class Administrators extends User{ public Administrators(String name) { super(name); } }
对象创建完毕,接下来就要开始让对象之间进行交互了。
前面我们看到了,不同的用户,根据选择的不同,会弹出不同功能菜单。这个有没有一种很熟悉的感觉,没错这就是我们在前面学习的多态。接下来就是要找多态的条件了:子类对象给到父类引用;子类重写父类当中的方法;通过父类引用调用被重写的方法。在上面的分析中,只有用户之间存在父子类关系。那么我们就可以在设计菜单时,根据选择的不同返回不同的用户对象。返回值就用父类接收,父类在调用功能菜单时,根据是哪一个子类,从而会调用不同的菜单。
登录菜单:
public static User login() { System.out.print("请输入您的姓名:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); System.out.println("请选择您的身份:1. 管理员;2. 普通用户"); int n = scanner.nextInt(); // 根据选择的不同,弹出不同的界面 (这里我们就可以采用多态的方式来写) while (true) { if (n == 1) { System.out.println("登录成功!"); // 如果是管理员就返回管理员对象 return new Administrators(name); }else if (n == 2) { System.out.println("登录成功!"); // 如果是普通用户就返回普通用户对象 return new RegularUsers(name); }else { System.out.println("登录失败,请重新选择您的身份!"); n = scanner.nextInt(); } } }
Main 方法:
public static void main(String[] args) { // 系统登录 User user = login(); // 创建一个书架 BookList bookList = new BookList(); while (true) { // 登录之后,就可以根据前面的选择弹出不同身份的界面 int choice = user.menu(); // 根据返回的选择,进行不同对象的不同的操作 // 对象已经确定了,接下来,就是进行不同的操作。 // 因为不同的对象包含不同的操作,所以我们可以把这个操作分成一个数组放到不同的类中 user.work(choice, bookList); // 操作的对象是书架,因此传入书架 } }
根据我们在功能页面的选择,来返回不同的值。接着调用work方法来实现不同的功能。这里同样运用了多态的思想。那么父类和子类同样都要有work方法。
父类:
public abstract class User{ protected String name; // 因为这个name其子类也得使用 public User(String name) { this.name = name; } public abstract int menu(); public abstract void work(int choice , BookList bookList); }
子类:
public class RegularUsers extends User{ protected IWork[] iWorks; public RegularUsers(String name) { super(name); // 注意顺序,要和功能菜单一致 this.iWorks = new IWork[]{new Exit(), new FindBook(), new BorrowBook(), new ReturnBook()}; } @Override public int menu() { System.out.println("*** 普通用户菜单 ***"); System.out.println("1. 查找图书"); System.out.println("2. 借阅图书"); System.out.println("3. 归还图书"); System.out.println("0. 退出系统"); System.out.println("******************"); System.out.print("请选择您要进行的操作:"); Scanner scanner = new Scanner(System.in); int choice = scanner.nextInt(); return choice; } public void work(int choice, BookList bookList) { // 通过对应的参数执行对应的操作 iWorks[choice].work(bookList); } }
public class Administrators extends User{ IWork[] iWorks; @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("******************"); System.out.print("请选择您要进行的操作:"); Scanner scanner = new Scanner(System.in); int choice = scanner.nextInt(); return choice; } public Administrators(String name) { super(name); // 注意顺序,要和功能菜单一致 this.iWorks = new IWork[]{new Exit(), new FindBook(), new AddBooks(), new DelBook(), new ShowBook()}; } @Override public void work(int choice, BookList bookList) { iWorks[choice].work(bookList); } }
因为操作是根据选择来分配的,也是可以用数组来进行接收,并且执行的。
public interface IWork { void work(BookList bookList); }
上面是一个IWork的接口,为了实现用数组接收,并且更好的管理各种功能。
实现基本功能
下面就是实现各种基本的功能了。
新增图书:
public class AddBooks implements IWork { @Override public void work(BookList bookList) { System.out.println("正在新增图书..."); // 其实就是在这个顺序表的数组中新增了一个元素 // 首先,得判断这个数组是否已经满了 // 使用的长度如果等于书架的长度了,就需要增加书架的长度了 if (bookList.getBooks().length == bookList.getUsedSize()) { System.out.println("书架已满,正在新增书架空间,请稍后..."); // 创建一个新的数组 Book[] newArray = Arrays.copyOf(bookList.getBooks(),2*bookList.getBooks().length); bookList.setBooks(newArray); System.out.println("书架空间新增成功!"); } System.out.println("请输入要新增的书名:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); System.out.println("请输入要新增的书的作者:"); String author = scanner.nextLine(); System.out.println("请输入要新增的书的价格:"); int price = scanner.nextInt(); scanner.nextLine(); System.out.println("请输入要新增的书的类型:"); String type = scanner.nextLine(); System.out.println("请输入要新增的书的数量:"); int count = scanner.nextInt(); // 判断该书是否已经存在。若已存在,只需把书的数量加上即可 for (int i = 0; i < bookList.getUsedSize(); i++) { if (bookList.getBooks()[i].getName().equals(name)) { System.out.println("该书已经存在了,因此增加数量即可"); bookList.getBooks()[i].setCount(count + bookList.getBooks()[i].getCount()); return; } } // 相当于 Books[4] = new Book(name, author, price, type, count); bookList.getBooks()[bookList.getUsedSize()] = new Book(name, author, price, type, count); bookList.setUsedSize(bookList.getUsedSize()+1); System.out.println("新增成功!"); } }
注意:Java中没有直接让数组空间大的方法,只能是拷贝一份比原来空间更大的数组。
借阅图书:
public class BorrowBook implements IWork{ @Override public void work(BookList bookList) { System.out.println("正在借阅图书..."); System.out.println("请输入您要借阅的书名:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); for (int i = 0; i < bookList.getUsedSize(); i++) { if (bookList.getBooks()[i].getName().equals(name)) { bookList.getBooks()[i].setLentCount(bookList.getBooks()[i].getLentCount()+1); System.out.println("书籍已自动发放到您的账户中,请注意查收!"); return; } } System.out.println("对不起!暂时没有您要找的书,书库会尽快更新哦~"); } }
借阅图书就是把书架上的书的属性修改一下即可。
删除图书:
public class DelBook implements IWork{ @Override public void work(BookList bookList) { System.out.println("正在删除图书..."); System.out.println("请输入您要删除的书名:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); // 注意这里查找与删除的范围 for (int i = 0; i < bookList.getUsedSize(); i++) { if (bookList.getBooks()[i].getName().equals(name)) { for (int j = i; j < bookList.getUsedSize()-1 ; j++) { bookList.getBooks()[j] = bookList.getBooks()[j+1]; } bookList.setUsedSize(bookList.getUsedSize()-1); System.out.println("删除成功!"); return; } } System.out.println("对不起!没有您要删除的书"); } }
删除图书本质就是让有效的长度变小,并且让后面的元素覆盖前面的元素。
退出系统:
public class Exit implements IWork{ @Override public void work(BookList bookList) { System.out.println("正在退出图书管理系统..."); System.exit(0); } }
JavaAPI中提供了一个方法可以直接强制停止程序(正常停止),就是System.exit(0),参数一定要是0才行。这会立即终止当前Java虚拟机,其中的参数0表示正常退出状态。但请注意,除非确实需要立即终止整个JVM(比如在命令行应用中),否则通常建议让程序自然执行到结束而不是使用上面的方法,以允许JVM进行清理工作。
查找图书:
public class FindBook implements IWork { @Override public void work(BookList bookList) { System.out.println("正在查找图书..."); System.out.println("请输入您要查找的书名:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); for (int i = 0; i < bookList.getUsedSize(); i++) { if (bookList.getBooks()[i].getName().equals(name)) { System.out.println("下面是您要查找的书籍的相关信息:"); System.out.println(bookList.getBooks()[i]); return; } } System.out.println("对不起!暂时没有您要找的书,书库会尽快更新哦~"); } }
查找图书就是遍历整个数组即可。
归还图书:
public class ReturnBook implements IWork{ @Override public void work(BookList bookList) { System.out.println("正在归还图书..."); System.out.println("请输入您要归还的书名:"); Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); for (int i = 0; i < bookList.getUsedSize(); i++) { if (bookList.getBooks()[i].getName().equals(name)) { bookList.getBooks()[i].setLentCount(bookList.getUsedSize()-1); System.out.println("归还成功!欢迎再次借书~"); return; } } System.out.println("对不起!暂时没有您要归还的书~"); } }
显示图书:
public class ShowBook implements IWork { @Override public void work(BookList bookList) { System.out.println("正在显示图书..."); for (int i = 0; i < bookList.getUsedSize(); i++) { System.out.println(bookList.getBooks()[i]); } } }
这里的显示图书,是显示所有图书,如果要显示单本图书,就是用查找图书的方法。
以上就是图书系统的基本功能啦!
这个图书系统是基于顺序表来实现的,如果有不懂的话,可以去看看那篇顺序表的博客(文章最前面)。
由于文件太多,不好全部把这些代码全部拷贝过来。
注意:上面的代码直接拷贝到编译器会报错的,因为没有导包,基本框架和IWork都是单独在包中的,Main方法是在源文件中单独存在的,并没有放入包中。
好啦!注意事项也讲完了,图书管理系统也基本实现啦!本期文章就到此结束啦!我们下一期再一起学习吧!
还没有评论,来说两句吧...