目录

 1、分析图书系统设计到的各种类和类的属性

  2、编写代码

【1】Book类

【2】BookList 类

【3】具体操作分析

【4】用户分类

【5】开始整合(最难)


先给大家展示一下完成后图书系统的样子

Java写一个信息系统 用java写操作系统_User

 接下来,主要讲解代码编写的思路,完整代码点击文字获取 图书管理小练习

 1、分析图书系统设计到的各种类和类的属性

写代码之前,我们先要大致抽象出来一些该有的类和类的属性。

在具体写代码的时候还会有一些部分添加

1)首先 图书系统 肯定要有 书,而我们要想准确描述一本书,我们就要创建一个书类(Book)

包含属性

  • 书名 name
  • 作者 author
  • 价格 price
  • 类型 type
  • 是否被借出 isBorrowed

2)有了书之后,就要有书架(用来存储书籍)。所以我们还要创建一个书架类 (BookList)

 包含属性

  • Book[] (存储书籍,可以要用数组来存储)

3)用户分类,我们的图书操作系统分为 【普通用户】和【管理员】,所以我们要创建 AdminUser类(管理员) 和 NormalUser 类(普通用户)

注意:不同的用户,打印的菜单不同,这里先提醒一下大家

4)各种操作类,我们还要创建一些来对书架进行操作(简称 操作类)。主要的操作如下

  1. 查找图书(FindOperation 类)
  2. 新增图书(AddOperation 类)  
  3. 删除图书(DelOperation 类)
  4. 显示图书(DisplayOperation 类)
  5. 归还图书(ReturnOperation 类)
  6. 借阅图书(BorrowOperation 类)
  7. 退出书架(ExitOperation 类)

以上我们就基本把这个图书操作系统各个部分分析完了,而为了方便我们管理,我们还要对这些类进行分门别类。

也就是说,我们在编写代码时,把不同的类放在不同包下,用包来对这些类进行封装

Java写一个信息系统 用java写操作系统_System_02

  2、编写代码

【1】Book类

我们首先来写 Book 类,把图书的各种特性创建成员变量,这些成员变量用 private 修饰

private String name;//书名
    private String author;//作者
    private int price;//价格
    private String type;//类型
    private boolean isBorrowed;//是否被借出

用 private 修饰体现封装

     同时因为这些成员变量是被 private 修饰,在类外不能获取,所以我们要写一系列 get 和 set 方法,方面我们类外获取和修改这些变量。

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

        然后,构造 Book 实例时,为了方便给成员变量赋值,所以我们也可以写一个构造方法。为了方便显示 书 的内容,我们还要写一个 toString 方法

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

构造方法里面没有给 isBorrowed 赋值,是因为 isBorrowed 是 bollean 类型的变量,创建的初始值为 false,方便我们后续的操作。所以不用再给 isBorrowed 赋值

到这里 Book 类算是完成啦,接下来就是 BookList 类。 

 【2】BookList 类

   单独的书的类型创建好了,现在就来创建一个 BookList 类用来存储书籍。

这个 BookList 就相当于 书架

   我这里用数组来存储多本书,创建一个 Book数组 类型的成员变量,存储容量大小为10

private Book[] books = new Book[10];

存储书籍也能用 ArrayList、LinkList等....这里为了方便理解,我用了数组 

   存储 书 的书架有了,那我们如何知道这个书架里面有多少本书呢?

    为了解决这个问题,再来创建一个成员变量来记录我们存储图书的数量

private int usedSize;//实时记录,当前books这个数组当中有多少本书

在书架中,我们可能要取书、存书等操作。而这些操作其实就是对 BookList 类中数组进行的操作,所以我们要在类中写一些方法来完成这些操作供外界使用。 

  • 通过下标获取书
  • 在某位置下放书
  • 获取 书架 中书的个数
  • 修改 书架 中书的个数
/**
     * @param pos pos一定是合法的
     * @return
     */
    public Book getBook(int pos){
        return books[pos];
    }

    /**
     * @param pos 此时pos一定是合法的
     * @param book 是你要放的书
     */
    public void setBooks(int pos,Book book){
        books[pos] = book;
    }
    
   /**
     * 实时获取当前书的个数
     * @return
     */
    public int getUsedSize(){return usedSize;}

    /**
     * 实时的修改当前书架上的书的个数
     */
    public void setUsedSize(int size){
        usedSize = size;
    }

为了方便我们后面的操作,当我们构造 BookList 对象时,先生成三本书

public BookList(){
        books[0] = new Book("三国演义","罗贯中",19,"小说");
        books[1] = new Book("西游记","吴承恩",19,"小说");
        books[2] = new Book("红楼明","曹雪芹",19,"小说");
        usedSize = 3;
    }

【3】具体操作分析

      这里我把把这些操作方法类全部都放到一个 operation 包下面!

      因为这些 “方法” 都是对 BookList进行操作,那我们是不是可以创建一个接口,来统一标准的规范

 0)IOperation 接口

public interface IOperation {
    void work(BookList bookList);
}

接下来,我们让具体的操作来实现这个接口 

        例如:添加图书 AddOperation 类

public class AddOperation implements IOperation{
    @Override
    public void work(BookList bookList) {
        System.out.println("添加图书");
    }
}

这里先不着急实现具体的业务逻辑,我们先把逻辑整理好 

其他的操作也是类似,这里就不在赘述了 

借阅图书 BorrowOperation

删除图书 DelOperation

展示图书 DisplayOperation

查找图书 FindOperation

归还图书 ReturnOperation

退出 ExitOperation

【4】用户分类

我们的用户分为两种,一种是管理员,另一种是普通用户。

虽然他们的操作不同,但是都是属于用户这一类,所以我们可以写一个父类 User,在父类中 定义属性和方法,然后让子类继承。这样子类就不必重复写哪些操作

0)父类 User

public class User {
    protected String name;//用户名

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

    public abstract int menu();//打印菜单
    //因为管理员和普通用户的菜单内容不一样,所以在父类中 menu 方法我们可以直接写为抽象方法
}

1)子类 AdminUuser 和 NormalUser

        我们让子类 AdminUuser 和 NormalUser 继承 父类 User,这样我们就不用重复定义 name这个属性。

继承父类后,我们要提供一个构造方法来显示的帮助父类构造!!!

注意:不同用户菜单不同!

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

    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 scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
    
}
public class NormalUser extends User{

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

    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 scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
}

这里用户逻辑也基本实现啦,现在我们开始整合这些类

【5】开始整合(最难)

这里我们新创建一个类 Main(这个类不在上面任何包内),创建一个 main方法。接下来我们将在该方法中整合所以部分。

Java写一个信息系统 用java写操作系统_父类_03

第一步:我们首先要准备我们的图书

BookList bookList = new BookList(); //准备图书

 这里我们不用一本书一本的创建放到 bookList 中,因为在 BookList 实例化时就准备好了三本书

Java写一个信息系统 用java写操作系统_Java写一个信息系统_04

第二步:开始登陆

这里我创建一个 login 方法,然后在 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){
            return new AdminUser(name);
        }else {
            return new NormalUser(name);
        }

    }

 为什么 login 方法的返回值是 User?因为 AdminUser 类 和 NormalUser 类都是 User 的子类,不管我们选择哪个角色进行实例化,User 都能接收 【向上转型】

 在 main 方法中,同样用 User接收

//登陆-> user 这个引用 引用那个对象
User user = login();

第三步:调用菜单,把具体操作跟菜单结合

因为上面我们一下选择 user 的实例化对象是管理员还是普通用户,所以我们直接调用menu 方法显示出来的菜单内容也是不一样的。

        所以我们要在 AdminUser 类 和 NormalUser 类分别定义 menu方法

AdminUser 类中 menu() 方法

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 scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
NormalUser 类中 menu() 方法
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 scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }


到这里还没结束,我们回到 Main类中,我们选择的用户类型是用 父类 User 接收的,

所以我们需要 user对象来调用 menu()。

此时编译器就会报错,原因就是 User 类中没有定义 menu,所以我们还要在 User 类中写一下menu() 方法

Java写一个信息系统 用java写操作系统_Java写一个信息系统_05

public abstract int menu();

父类中的 menu方法不需要具体实现,定义为抽象类就行。

此时我们在用 user调用就不会出错了,menu() 方法会动态绑定!!!

【我们选的哪个就会打印哪个的菜单】

Java写一个信息系统 用java写操作系统_User_06

Java写一个信息系统 用java写操作系统_Java写一个信息系统_07

         然后我们创建一个变量来接收用户的选择

int choice = user.menu();//动态绑定

 我们来看不同用户的菜单,在管理员菜单中 ‘2’ 是新增图书,而在普通用户菜单菜单中 ‘2’ 是借阅图书。

现在问题来了,我们如何才能知道用户想要执行那个 ‘2’ 操作呢?

我们是不是可以让  AdminUuser 对象和 NormalUser 对象中分别存储好各种要执行的操作就可以了。

现在我们重新回到 User类中,添加一个成员

protected IOperation[]  iOperations;//此时并没有初始化和分配大小

然后分别在 AdminUuser 和 NormalUser 各自的抽象方法中各自初始化具体的内容

Java写一个信息系统 用java写操作系统_父类_08

最后,在父类 User 中再定义一个具体调用哪个操作的方法

public void doOperation(int choice, BookList bookList){
        this.iOperations[choice].work(bookList);
    }

这样我们就能根据用户选择来决定实现那种方法啦 

通过 choice 作为下标,来找到具体的执行类并执行类中的方法

Java写一个信息系统 用java写操作系统_父类_09

 为什么 doOperation 方法分别定义在  AdminUuser 和 NormalUser 中?

        因为如果定义在  AdminUuser 和 NormalUser 中,在整合时 use 对象就无法调用 doOperation 方法。

Java写一个信息系统 用java写操作系统_父类_10