网站开发需求说明书网站建设案例 算命网站
一、图书管理系统菜单
 🍓管理员菜单
1.查找图书
2.新增图书
3.删除图书
4.显示图书
0.退出系统
---------------------------------------------------------------------------------------------------------------------------------
🌼用户菜单
1.查找图书
2.借阅图书
3.归还图书
0.退出系统
二、实现基本框架
 先建立一个新的文件,命名为TestBook,在文件内建立两个包,分别命名为user(用户)、book(图书)。
先写book相关的代码。于是,我们先在book包中新建一个java类,名为:Book。
显示图书时,我们希望它能显示出所有图书的名称、作者、价格、类型和图书目前是否借出。
  private String name;//书名
     private String author;//作者
     private int price;//价格
     private String type;//类型
     private boolean isBorrowed;//是否被借出,初始值是false,在构造方法中不用写
  右击鼠标,选择Generate,选择Getter and Setter 选项,点击shift,点最后一个,就能全选:
自动生成:
 
     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;
     }
再写它们的构造方法:
当我们新增一本图书时,它默认就是未被借出的,所以不用构造方法。
快捷键:alt+insert。按ctrl,可以多选,直接生成下面代码块:
 
     public Book(String name, String author, int price, String type) {//构造方法
         this.name = name;
         this.author = author;
         this.price = price;
         this.type = type;
     }
  我们再右键选择Generate,选择ToString,全选,点OK,自动生成:
  @Override
     public String toString() {
         return "Book{" +
                 "name='" + name + '\'' +
                 ", author='" + author + '\'' +
                 ", price=" + price +
                 ", type='" + type + '\'' +
                 ", isBorrowed=" + isBorrowed +
                 '}';
     }
 此时,在book包中新建一个类:BookList(书架):
在这个书架中,我们希望能在里面固定的位置放书,并且能知道放了几本书:
    private  Book[] books=new  Book[10];//这个书架可以放十本书
     private int usedSize;//记录下当前book数组中有几本书
 然后依旧是右键Generate ,getter and setter,自动生成:
当前界面:
我们还记得在C语言中,我们用到的 define,用define语句来定义一个常量,同理,我们这边也可以定义一个能放多少本书的常量:
  private static final int DEFAULT_SIZE=10;
   private  Book[] books=new  Book[DEFAULT_SIZE];
 我们这边就是先按思路慢慢写,慢慢补充。在后面,我会放完整的代码。
book包已经告一段落了,现在来写user包。
我们在user包中新建三个类:AdminUser(管理员)、NormalUser(用户)、User。
NormalUser、AdminUser,这也就是我们图书管理系统面对的两个对象了,管理员和用户,他们具有一些相同的属性。我们就可以写一个User类,让两个类去继承,来省一些代码了。
🥗我们先写User类叭~
package user;
  
 public class User {
     protected String name;//名字.这边的protect代表的是名字的权限。如果是private,它只能在同一个包的同一类使用。就不能让AdminUser类继承了。
     //写public的话,权限太大了,不是很好。
     public User(String name) {//构造方法
         this.name = name;
     }
 }
 所以在AdminUser类中:
package user;
  
 public class AdminUser extends User{
     public AdminUser(String name) {
         super(name);
     }
 }
 可以直接用快捷键,alt+insert,直接生成构造方法。
同理,NormalUser类中:
package user;
  
 public class NormalUser extends User{
     public NormalUser(String name) {
         super(name);
     }
 }
  
 我们书的属性和用户属性的包和类已经写了大概。我们现在回归到我前面列的功能上:
然后,我们就会发现我们想要实现的功能和操作基本上是针对图书的。所以,这边,我们可以选择直接在图书book包中写方法,也可以选择另外再创建一个包。
我这边是新建了一个包,命名为:opera,再创建一个接口命名为IOPeration。
创建接口:点oper,右击,点击java Class:
然后页面为:
创建接口:
package opera;
  
 import book.BookList;
  
 public interface IOPeration {//创建接口
     void work(BookList bookList);//抽象方法
     //功能主要是针对图书的,也就是针对书架。
 }
  我们在opera(实现功能的包)中,创建两个类,AddOperation、FindOperation,这两个类。
我们会发现这两个类的实现也都要依靠BookList(书架)来实现。所以,在这两个类中,实现接口:
FindOperation类中:
package opera;
  
 import book.BookList;
 public class FindOperation implements IOPeration{//继承
     @Override
     public void work(BookList bookList) {//重写IOPeration类中的work方法
         System.out.println("查找图书!");
     }
 }
 AddOperation类中:
package opera;
  
 import book.BookList;
  
 public class AddOperation implements IOPeration {
     public void work(BookList bookList){
         System.out.println("新增图书!");
     }
 }
  同理,新建类DelOperation(删除图书):
package opera;
  
 import book.BookList;
  
 public class DelOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("删除图书!");
     }
 }
  新建一个类:ShowOperation(显示图书):
package opera;
  
 import book.BookList;
  
 public class ShowOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("打印所有图书!");
     }
 }
  再新建一个类:ExitOperation(退出系统):
package opera;
  
 import book.BookList;
  
 public class ExitOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("退出系统!");
     }
 }
 新建一个BrrowOperation类(借阅图书):
package opera;
  
 import book.BookList;
  
 public class BrrowOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("借阅图书!");
     }
 }
  再新建一个类:ReturnOperation(借阅图书):
package opera;
  
 import book.BookList;
  
 public class ReturnOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("归还图书!");
     }
 }
 接着,我们来细化我们的类。
🍅我们还没有给user添加菜单。
我们先给管理员添加菜单:
    public void menu(){
         System.out.println("____________________________________");
         System.out.println("1.查找图书");
         System.out.println("2.新增图书");
         System.out.println("3.删除图书");
         System.out.println("4.显示图书");
         System.out.println("0.退出系统");
     }
 再给用户添加菜单:
public void manu(){
     System.out.println("_________________");
     System.out.println("hello,"+name+"~");
     System.out.println("1.查找图书!");
     System.out.println("2.借阅图书!");
     System.out.println("3.归还图书!");
     System.out.println("0.退出系统!");
 }
 现在,我们写main方法。在src下新建一个类:Main:
import user.AdminUser;
 import user.NormalUser;
 import user.User;
  
 import java.util.Scanner;
  
 public class Main {
     //登录
         public static User login(){
             System.out.println("请输入你的姓名:");
             Scanner scanner=new Scanner(System.in);
             String name=scanner.nextLine();
             System.out.println("请选择你的身份:1->管理员 0->普通用户");
             int choice =scanner.nextInt();
             if(choice==1){
                 //说明是管理员
                 //由于有返回值,所以我们的方法返回值就不能写void了。但是我们也无法确定返回值是什么,可能是管理员,可能是用户。所以,用向上转型,写User.
                 return new AdminUser(name);//返回实例化一个管理员对象
             }else {
                 return new NormalUser(name);//返回实例化一个用户对象
             }
         }
     public static void main(String[] args) {
   User user=login();//执行上面的login方法
         user.menu();//实现打印菜单
     }
 }
执行login方法时,我们是还不知道new的对象是管理员还是用户的。所以,在打印菜单时,我们也不能直接使用我们在AdminUser类和NormalUser类中写的menu()方法。
✨🎉所以在写user.menu();这个语句时,不行!
所以,我们想到了重写。
我们把User类改成抽象类,在抽象类中写一个menu的抽象方法。
package user;
 public abstract class User {//抽象类
     protected String name;//名字.这边的protect代表的是名字的权限。如果是private,它只能在同一个包的同一类使用。就不能让AdminUser类继承了。写public的话
     //权限太大了,不是很好。
     public User(String name) {//构造方法
         this.name = name;
     }
     public abstract void menu();//抽象方法,打印菜单
 }
 那么, 在AdminUser类和NormalUser类中,也应该有相应的改动,把里面的menu()写成重写的形式。
这也仅仅是实现了打印菜单:
这个过程还是有一些弯弯绕绕的。我们可以通过调试,来捋清我们的思路:
调试的话:
然后,编译器就会带我们一步步地看它是怎么执行的。
接着,我们继续完善我们的代码。光打印一个菜单,不执行我们想要的功能,可不行。
所以,我们在我们的menu菜单中,需要输入我们的功能选择:
   Scanner scanner=new Scanner(System.in);
         int choice=scanner.nextInt();
         return choice;
 输入功能选择,我们就要通过这个选择就实现:
首先,我们要根据对象(管理员或用户),选择引用哪一个菜单方法:
NormalUser类中:
 public NormalUser(String name) {
         super(name);
         this.ioPerations=new IOPeration[]{//引用,这边用super也可以,因为这里没有同名的,不需要做区分。用this最好
                 new FindOperation(),
                 new BrrowOperation(),
                 new ReturnOperation(),
                 new ExitOperation()//以动态方式申请内存。拿到变量后,我们就给他们分配内存
         };
  AdminUser类中:
  public AdminUser(String name) {
         super(name);
         this.ioPerations=new IOPeration[]{
                 new ExitOperation(),
                 new FindOperation(),
                 new AddOperation(),
                 new DelOperation(),
                 new ShowOperation()
         };
     }
  当我们在构造方法中,写了这些,也就为它们分配了内存。当main类中login()方法下,new一个对象时,就会执行相应的构造方法,在这里就是开辟内存:
在User类中:
我们加上这样一段代码:
 public void doWork(int choice, BookList bookList){//通过选择的操作,去选择执行数组下的哪个操作
         this.ioPerations[choice].work(bookList);
     }
 this.ioPerations[choice]其实就是new了一个对象。后面的.work(bookList)是调用图书中对应的work方法。
由此一来,我们就可以根据我们一步步的选择,调用book包中对应的work方法。
为了让代码在输入0的时候退出系统,我们用while语句(在Main方法中修改):
   while (true){
             int choice=user.menu();//实现打印菜单
             user.doWork(choice,bookList);
         }
  
这下子基本框架就构造好了。
先看一下测试结果:
 三、实现业务
 3.1 打印所有图书
  我们先在BookList类,也就是书架中先添加图书:
public BookList(){//构造方法
         books[0]=new Book("《三国演义》","罗贯中",40,"小说");
         books[1]=new Book("《西游记》","吴承恩",60,"小说");
         books[2]=new Book("《红楼梦》","曹雪芹",45,"小说");
         this.usedSize=3;
     }
    //通过这个方法,实现ShowOperation中的通过下标打印数组元素
     public Book getBook(int pos){
         return this.books[pos];
     }
 然后,我们实现打印所有图书这个业务 。
🍍在ShowOperation类中,添加打印所有图书的程序,利用for循环。
在ShowOperation类中:
package opera;
  
 import book.BookList;
  
 public class ShowOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("显示图书!");
         int currentSize= bookList.getUsedSize();
         for (int i=0;i<currentSize;i++){
             System.out.println(bookList.getBook(i));
         }
     }
 }
 实现的结果:
我们会发现一些小瑕疵,比如这边输出的false。我们想把它改成已借出,未借出。
这时,我们要用到三目运算符。条件?符合输出:不符合输出
在book类中修改:
  public String toString() {
         return "Book{" +
                 "name='" + name + '\'' +
                 ", author='" + author + '\'' +
                 ", price=" + price +
                 ", type='" + type + '\'' +
                 ", isBorrowed=" +(isBorrowed==true?"    已借出":"    未借出") +
                 '}';
     }
  3.2 退出系统
 退出系统很简单,只需要加上👇语句即可。0代表正常退出。
System.exit(0);
  实现结果:
 3.3 查找图书
 查找图书是跟刚才打印图书差不多的思路。通过for循环,利用equal()进行比对,输出图书信息。
在FindOperation类中补充代码:
public class FindOperation implements IOPeration{//继承
     @Override
     public void work(BookList bookList) {//重写IOPeration类中的work方法
         System.out.println("查找图书!");
         System.out.println("请输入要查找的图书名字");
         Scanner scanner=new Scanner(System.in);
        String name=scanner.nextLine();
        int currentSize= bookList.getUsedSize();
        for (int i=0;i<currentSize;i++){
            Book book=bookList.getBook(i);
            if(book.getName().equals(name)){//判断查找图书名字是否相同
                System.out.println("查到了:");
                System.out.println(book);//输出图书信息
            }else {
                System.out.println("没有这本书");
            }
        }
     }
  
 }
 3.4 增加图书
 我们要先输入新增图书信息,new一个对象,判断这本图书是否已经存在,如果不存在,则存入书架中。
AddOperation类:
package opera;
  
 import book.Book;
 import book.BookList;
  
 import java.util.Scanner;
  
 public class AddOperation implements IOPeration {
     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("请输入价格");
        int price=scanner.nextInt();
         Scanner scanner2=new Scanner(System.in);
         System.out.println("请输入小说类型:");
         String type=scanner2.nextLine();
         Book book=new Book(name,author,price,type);
         int currentSize= bookList.getUsedSize();
         for (int i=0;i<currentSize;i++){
             Book temp=bookList.getBook(i);
             if(temp.getName().equals(name)){//判断查找图书名字是否相同
                 System.out.println("已经有这本书了");
                 return;
             }
         }
      bookList.setBooks(book);
         System.out.println("新增图书成功!");
         //修改图书数量
         bookList.setUsedSize(currentSize+1);
     }
 }
bookList.setBooks(book);这个语句,我们需要在书架那个类加上setBooks()方法:
  public void setBooks(Book book){
         this.books[usedSize]=book;
     }
  🍓注意!!!
 在增加图书的时候,我遇到了困难。
我在价格的地方,设置的是int类型。 int price=scanner.nextInt();这个语句执行完,它就不会执行后面的输入语句了。这是我疏忽的一个点。
有三种解决方案。
1.像我上面的代码一样,多写一个 Scanner scanner2=new Scanner(System.in); 这是改动最小的方法了。
2.就是把图书的价格和类型的顺序调换一下,就是要几个文件都改一小下,其实也很快。这样子int price=scanner.nextInt();,最后输这个输入命令的话,就能保证输入命令全部执行
3.这个方法也比较简单,就是把图书的价格类型改成String,那样子,就没有影响了。
3.5 删除图书 
 🍆删除图书,我们要注意,不仅仅是把那本书删除就好了,还需要把后面的书往前挪。
DelOperation类:
   public void work(BookList bookList) {
         System.out.println("删除图书!");
         System.out.println("请输入要删除图书的名称");
         Scanner scanner=new Scanner(System.in);
         String name=scanner.nextLine();
         int currentSize= bookList.getUsedSize();
         int index=-1;
         for (int i=0;i<currentSize;i++){
             Book temp=bookList.getBook(i);
             if(temp.getName().equals(name)){//判断查找图书名字是否相同
                 index=i;
                 break;
             }
         }
         //删除图书,把后面的图书往前面挪
         for (int j=index;j<currentSize-1;j++){
             Book book=bookList.getBook(j+1);//拿到j下标后面的书
             bookList.setBooks(j,book);//放到j下标的位置
         }
         bookList.setUsedSize(currentSize-1);//修改size值
         bookList.setBooks(currentSize-1,null);//因为删除的是对象,所以把地址置为null,就没有人引用了
     }
BookList类:
  public void setBooks(int pos,Book book){
         this.books[pos]=book;
     }
 我们可以注意到在BookList新添加的这个方法跟刚才在写增加图书时放置图书的方法相似。不过,我们可以注意到,增加图书,就是在最后面放一本书,就好了。而这里,是把后面的书一本本往前挪一个书位。
3.6 借阅图书
 思路:判断图书是否在书库中存在,判断图书是否已经被借出。满足条件,执行
temp.setBorrowed(true);
 3.7 归还图书 
 思路:判断图书是否在书库中存在,判断书是否已被借出。
满足条件:
temp.setBorrowed(false);
 总代码
 Book:
package book;
  
 public class Book {
     private String name;//书名
     private String author;//作者
     private int price;//价格
     private String type;//类型
     private boolean isBorrowed;//是否被借出,初始值是false,在构造方法中不用写
  
     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;
     }
  
     @Override
     public String toString() {
         return "Book{" +
                 "name='" + name + '\'' +
                 ", author='" + author + '\'' +
                 ", price=" + price +
                 ", type='" + type + '\'' +
                 ", isBorrowed=" +(isBorrowed==true?"    已借出":"    未借出") +
                 '}';
     }
  
     public void setBorrowed(boolean borrowed) {
         isBorrowed = borrowed;
     }
 }
BookList
package book;
 //书架
 public class BookList {
     private static final int DEFAULT_SIZE=10;
     private  Book[] books=new  Book[DEFAULT_SIZE];//这个书架可以放十本书
     public BookList(){//构造方法
         books[0]=new Book("《三国演义》","罗贯中",40,"小说");
         books[1]=new Book("《西游记》","吴承恩",60,"小说");
         books[2]=new Book("《红楼梦》","曹雪芹",45,"小说");
         this.usedSize=3;
     }
     //通过这个方法,实现ShowOperation中的通过下标打印数组元素
     public Book getBook(int pos){
         return this.books[pos];
     }
     public void setBooks(Book book){
         this.books[usedSize]=book;
     }
     public void setBooks(int pos,Book book){
         this.books[pos]=book;
     }
     private int usedSize;//记录下当前book数组中有几本书
     public int getUsedSize() {
         return usedSize;
     }
     public void setUsedSize(int usedSize) {
         this.usedSize = usedSize;
     }
 }
AddOperation
package opera;
  
 import book.Book;
 import book.BookList;
  
 import java.util.Scanner;
  
 public class AddOperation implements IOPeration {
     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("请输入价格");
        int price=scanner.nextInt();
         Scanner scanner2=new Scanner(System.in);
         System.out.println("请输入小说类型:");
         String type=scanner2.nextLine();
         Book book=new Book(name,author,price,type);
         int currentSize= bookList.getUsedSize();
         for (int i=0;i<currentSize;i++){
             Book temp=bookList.getBook(i);
             if(temp.getName().equals(name)){//判断查找图书名字是否相同
                 System.out.println("已经有这本书了");
                 return;
             }
         }
      bookList.setBooks(book);
         System.out.println("新增图书成功!");
         //修改图书数量
         bookList.setUsedSize(currentSize+1);
     }
 }
BorrwOperation:
package opera;
  
 import book.Book;
 import book.BookList;
  
 import java.util.Scanner;
  
 public class BrrowOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("借阅图书!");
         System.out.println("请输入要借阅的图书名字:");
         Scanner scanner=new Scanner(System.in);
         String name=scanner.nextLine();
         int curentSize= bookList.getUsedSize();
         int x=1;
         for(int i=0;i<curentSize;i++){
             Book temp=bookList.getBook(i);
             if((temp.getName().equals(name))&&!temp.isBorrowed()){
                {
  
                     temp.setBorrowed(true);
                     x=0;
                    System.out.println("借阅成功!");
                    return;
                 }
             }
         }
         if(x==1){
             System.out.println("没有该图书");
         }
     }
 }
DelOperation:
package opera;
  
 import book.Book;
 import book.BookList;
  
 import java.util.Scanner;
  
 public class DelOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("删除图书!");
         System.out.println("请输入要删除图书的名称");
         Scanner scanner=new Scanner(System.in);
         String name=scanner.nextLine();
         int currentSize= bookList.getUsedSize();
         int index=-1;
         int z=0;
         for (int i=0;i<currentSize;i++){
             Book temp=bookList.getBook(i);
             if(temp.getName().equals(name)){//判断查找图书名字是否相同
                 index=i;
                 z=1;
                 break;
             }
         }
         if(z==0){
             System.out.println("没有这本书!");
             return;
         }
         //删除图书,把后面的图书往前面挪
         for (int j=index;j<currentSize-1;j++){
             Book book=bookList.getBook(j+1);//拿到j下标后面的书
             bookList.setBooks(j,book);//放到j下标的位置
         }
         bookList.setUsedSize(currentSize-1);//修改size值
         bookList.setBooks(currentSize-1,null);//因为删除的是对象,所以把地址置为null,就没有人引用了
         System.out.println("删除成功!");
     }
  
 }
ExitOperation:
package opera;
  
 import book.BookList;
  
 public class ExitOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("退出系统!");
         System.exit(0);//退出系统。0代表正常退出
     }
 }
  FindOperation:
package opera;
  
 import book.Book;
 import book.BookList;
  
 import java.util.Scanner;
  
 public class FindOperation implements IOPeration{//继承
     @Override
     public void work(BookList bookList) {//重写IOPeration类中的work方法
         System.out.println("查找图书!");
         System.out.println("请输入要查找的图书名字");
         Scanner scanner=new Scanner(System.in);
        String name=scanner.nextLine();
        int currentSize= bookList.getUsedSize();
        for (int i=0;i<currentSize;i++){
            Book book=bookList.getBook(i);
            if(book.getName().equals(name)){//判断查找图书名字是否相同
                System.out.println("查到了:");
                System.out.println(book);//输出图书信息
                return;
            }
        }
         System.out.println("没有这本书!");
     }
  
 }
IOPeration:
package opera;
  
 import book.BookList;
  
 public interface IOPeration {//创建接口
     void work(BookList bookList);//抽象方法
     //功能主要是针对图书的,也就是针对书架。
 }
  ReturnOperation:
package opera;
  
 import book.Book;
 import book.BookList;
  
 import java.util.Scanner;
  
 public class ReturnOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("归还图书!");
         System.out.println("请输入要归还的图书名字:");
         Scanner scanner=new Scanner(System.in);
         String name=scanner.nextLine();
         int curentSize= bookList.getUsedSize();
         for(int i=0;i<curentSize;i++){
             Book temp=bookList.getBook(i);
             if((temp.getName().equals(name))&&temp.isBorrowed()){
                 {
                     temp.setBorrowed(false);
                     System.out.println("归还成功!");
                     return;
                 }
             }
         }
     }
     }
ShowOperation:
package opera;
  
 import book.BookList;
  
 public class ShowOperation implements IOPeration{
     @Override
     public void work(BookList bookList) {
         System.out.println("显示图书!");
         int currentSize= bookList.getUsedSize();
         for (int i=0;i<currentSize;i++){
             System.out.println(bookList.getBook(i));
         }
     }
 }
 Main
import book.BookList;
 import user.AdminUser;
 import user.NormalUser;
 import user.User;
  
 import java.util.Scanner;
  
 public class Main {
     //登录
     public static User login() {
         System.out.println("请输入你的姓名:");
         Scanner scanner = new Scanner(System.in);
         String name = scanner.nextLine();
         System.out.println("请选择你的身份:1->管理员 0->普通用户");
         int choice = scanner.nextInt();
         if (choice == 1) {
             //说明是管理员
             //由于有返回值,所以我们的方法返回值就不能写void了。但是我们也无法确定返回值是什么,可能是管理员,可能是用户。所以,用向上转型,写User.
             return new AdminUser(name);//返回实例化一个管理员对象
         } else {
             return new NormalUser(name);//返回实例化一个用户对象
         }
     }
  
     public static void main(String[] args) {
         User user = login();//执行上面的login方法
         BookList bookList = new BookList();
         while (true) {
             int choice = user.menu();//实现打印菜单
             user.doWork(choice, bookList);
         }
     }
 }
测试的话,运行Main:
user代码
AdminUer
package user;
  
 import opera.*;
  
 import java.util.Scanner;
  
 public class AdminUser extends User{
     public AdminUser(String name) {
         super(name);
         this.ioPerations=new IOPeration[]{
                 new ExitOperation(),
                 new FindOperation(),
                 new AddOperation(),
                 new DelOperation(),
                 new ShowOperation()
         };
     }
     @Override
     public int menu() {//因为返回值choice是int类型的
         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);
         int choice=scanner.nextInt();
         return choice;
     }
  
 }
NormalUser
package user;
  
 import opera.*;
  
 import java.util.Scanner;
  
 public class NormalUser extends User{
     public NormalUser(String name) {
         super(name);
         this.ioPerations=new IOPeration[]{//引用,这边用super也可以,因为这里没有同名的,不需要做区分。用this最好
                 new ExitOperation(),
                 new FindOperation(),
                 new BrrowOperation(),
                 new ReturnOperation()
                 //以动态方式申请内存。拿到变量后,我们就给他们分配内存
         };
     }
  
     @Override
     public int menu() {
         System.out.println("_________________");
         System.out.println("hello,"+name+"~");
         System.out.println("1.查找图书!");
         System.out.println("2.借阅图书!");
         System.out.println("3.归还图书!");
         System.out.println("0.退出系统!");
         Scanner scanner=new Scanner(System.in);
         int choice=scanner.nextInt();
         return choice;
     }
User
package user;
  
 import book.BookList;
 import opera.IOPeration;
  
 public abstract class User {//抽象类
     protected String name;//名字.这边的protect代表的是名字的权限。如果是private,它只能在同一个包的同一类使用。就不能让AdminUser类继承了。写public的话
     //权限太大了,不是很好。
     protected IOPeration[] ioPerations;
     public User(String name) {//构造方法
         this.name = name;
     }
     public abstract int menu();//抽象方法,打印菜单,因为有了choice返回值int类型,所以void改成int
     public void doWork(int choice, BookList bookList){//通过选择的操作,去选择执行数组下的哪个操作
         this.ioPerations[choice].work(bookList);
     }
 }
