【Java刷题】-图书项目(封装、继承、多态)

作者:学Java的冬瓜
博客主页:☀冬瓜的主页
专栏:【Java刷题】

文章目录

  • 前言
  • 实现图书
    • 1、Main
    • 2、User包
      • 2.1、User
      • 2.2、AdminUser
      • 2.3、NormalUser
    • 3、Book包
      • 3.1、Book
      • 3.2、BookList
    • 4、operation包
      • 4.1、Add
      • 4.2、Delete
      • 4.3、Find
      • 4.4、Modify
      • 4.5、Display
      • 4.6、Exit
      • 4.7、Borrow
      • 4.8、Return
  • 总结
      • 1、找对象
      • 2、整体把握,构建框架
      • 3、选择合适的方法位置

前言

学习目标:

前面学习了类和对象的相关知识、面向对象的三大特征:封装,继承和多态。今天本文的目的:

  1. 这些知识运用到具体的实际问题中,来解决图书管理的问题
  2. 初步认识面向对象编程的思想和方法

实现图书

1、Main

Main:

import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;  //必须有User调用,不然login返回值不能是User

import java.util.Scanner;

public class Main {
    public static User login() {
        System.out.println("请输入你的名字:>");
        Scanner scanner = new Scanner(System.in);
        String userName = scanner.nextLine();

        System.out.println("请输入你的身份: 1、管理员   2、普通用户:>");
        int choice = scanner.nextInt();

        //确保输入1或者2
        while (choice !=1 && choice!=2) {
            System.out.println("输入错误,请重新输入!");
            System.out.println("请输入你的身份: 1、管理员   2、普通用户:>");
            choice = scanner.nextInt();
        }
        //1、返回new的对象
        //2、new的时候初始化对象的name
        //3、用User类型对象接收new的对象,发生向上转型
        if(choice==1) {
            return new AdminUser(userName);
        } else { //choice==2
            return new NormalUser(userName);
        }
    }

    public static void test() {
        //0、准备书架  ,初始化放三本书
        BookList bookList = new BookList();


        //1、登录
        User user = login(); //用User类型对象接收AdminUser或NormalUser类型的对象,发生向上转型

        while(true){
            //2、打印菜单并返回选择
            int choice = user.menu();//发生多态(还有动态绑定)

            //3、调用整合操作方法,进行操作
            user.doOperations(choice,bookList);
        }

    }
    public static void main(String[] args) {
        test();//用test函数测试
    }
}

2、User包

2.1、User

package user;
import book.BookList;
import operation.IOperation;

/**
 *  父类
 **/
public abstract class User {
    //封装name
    private String name;

    //不用private,不然在子类中访问iOperations并初始化很麻烦
    protected IOperation[] iOperations;//只是定义了接口数组但没有初始化,内存也未分配


    //1、需要管理员和普通用户相对应的两个菜单,所以设置成继承,进而可以使用多态
    //2、父类中的menu不需要任何操作,所以可以改为抽象类
    public abstract int menu();

    public void doOperations(int choice, BookList bookList) {
        this.iOperations[choice].work(bookList);//先得到choice下标的操作对象,再调用work方法
    }


    //构造方法初始化name
    public User(String name) {
        this.name=name;
    }

    //获取name
    public String getName() {
        return name;
    }
}

2.2、AdminUser

package user;
import operation.*;
import java.util.Scanner;

/**
 * 管理员
 */
public class AdminUser extends User{

    //login中返回new的对象时,name和iOperation都完成初始化
    public AdminUser(String name) {
        super(name);//调用父类构造方法完成初始化

        this.iOperations = new IOperation[] {
                new Exit(),
                new Add(),
                new Delete(),
                new Find(),
                new Modify(),
                new Display(),
        };
    }

    public int menu() {
        System.out.println("*********************************");
        System.out.println("hello "+this.getName()+" 欢迎来到图书小练习!");
        System.out.println("*********************************");
        System.out.println("1、增添图书     2、删除图书");
        System.out.println("3、查找图书     4、修改图书");
        System.out.println("5、显示图书     0、退出系统");
        System.out.println("*********************************");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的选择:>");
        int choice = scanner.nextInt();

        while(choice <0 || choice>=6) {
            System.out.println("输入错误,请重新选择!");
            System.out.println("请输入你的选择:>");
            choice = scanner.nextInt();
        }
        return choice;

    }
}

2.3、NormalUser

package user;
import operation.*;
import java.util.Scanner;

/**
 * 普通用户
 */
public class NormalUser extends User{

    //在子类构造方法中调用父类构造方法完成父类name的初始化
    public NormalUser(String name) {
        super(name);

        this.iOperations = new IOperation[] {
                new Exit(),
                new Find(),
                new Borrow(),
                new Return()
        };
    }

    public int menu() {
        System.out.println("*********************************");
        System.out.println("hello "+this.getName()+" 欢迎来到图书小练习!");
        System.out.println("*********************************");
        System.out.println("1、查找图书     2、借阅图书");
        System.out.println("3、归还图书     0、退出系统");
        System.out.println("*********************************");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的选择:>");
        int choice = scanner.nextInt();

        while(choice <0 || choice>=4) {
            System.out.println("输入错误,请重新选择!");
            System.out.println("请输入你的选择:>");
            choice = scanner.nextInt();
        }
        return choice;
    }
}

3、Book包

3.1、Book

package book;

public class Book {
    private String name;
    private String author;
    private int price;
    private String type;  //图书类型
    private boolean isBorrowed; //图书是否借出

    //创建构造方法,在new时传入并初始化书的信息
    public Book(String name, String author, int price, String type) {
        this.name = name;
        this.author = author;
        this.price = price;
        this.type = type;
    }


    //查找等各种操作都需要输入图书名字,所以需要getName访问book的name信息
    public String getName() {
        return name;
    }


    //借阅和归还都需要设置book中的boolean值
    public void setBorrowed(boolean borrowed) {
        isBorrowed = borrowed;
    }

    //打印时防止打印book对象的地址,重写object类的toString方法
    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ", isBorrowed=" + ((isBorrowed == false) ? "未借出" : "已借出") +
                '}';
    }
}

3.2、BookList

package book;

/**
 * 书架
 */
public class BookList {
    //封装books和usedSize
    private Book[] books = new Book[10];
    private int usedSize;

    //构造方法,new书架bookList的时候,books中默认放入三本书
    public BookList() {
        books[0] = new Book("水浒传","施耐庵",59,"小说");
        books[1] = new Book("西游记","吴承恩",38,"小说");
        books[2] = new Book("三国演义","罗贯中",89,"小说");
        this.usedSize = 3; //书的有效个数初始值

    };

    //用Add调用setPosBook是尾插法,Modify调用是是修改该位置
    public void setPosBooks(int pos, Book book) {
        this.books[pos] = book;
    }

    public Book getPosBooks(int pos) {
        return this.books[pos];
    }

    public int getUsedSize() {
        return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }
}

//可以在这里,在BookList类中写增删查改等方法,来实现对Book[]类型的books操作

4、operation包

4.1、Add

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class Add 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.nextLine();//接收上一步留下的回车键
        System.out.println("请输入图书类型:>");
        String type = scanner.nextLine();

        //创建一个Book类型的对象存储这本书
        Book book = new Book(name,author,price,type);
        //把书放进书架(这里相当于尾插)
        int currentUserSize = bookList.getUsedSize();
        bookList.setPosBooks(currentUserSize,book);
        bookList.setUsedSize(currentUserSize+1);
        System.out.println("增添成功!");
    }
}

4.2、Delete

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class Delete implements IOperation{
    //添加要完善的话,也可以用和Delete相同地方法
    public void work(BookList bookList) {
        System.out.println("==删除图书==");

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

        int index=-1;
        int currentUsedSize = bookList.getUsedSize();
        for (int i = 0; i < currentUsedSize; i++) {
            Book book = bookList.getPosBooks(i);
            if(book.getName().equals(name)) {//字符串的比较,用equals
                index=i;
                break;
            }
        }
        if(index==-1){
            System.out.println("没有你要删除的书!");
        } else {
            int start=index+1;
            while(start<currentUsedSize) {
                Book book = bookList.getPosBooks(start);
                bookList.setPosBooks(start-1,book);
                start++;
            }
            bookList.setPosBooks(currentUsedSize-1,null);
            bookList.setUsedSize(currentUsedSize-1);
            System.out.println("删除成功!");
        }
    }
}

4.3、Find

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class Find implements IOperation{
    public void work(BookList bookList) {
        System.out.println("==查找图书==");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入图书名字:>");
        String name = scanner.nextLine();
        int currentUsedSize = bookList.getUsedSize();
        for (int i = 0; i < currentUsedSize; i++) {
            Book book = bookList.getPosBooks(i);
            if(book.getName().equals(name)) {//字符串的比较,用equals
                System.out.println("找到了!");
                System.out.println(book);
                return;
            }
        }
        System.out.println("没有你要查找的书!");
    }
}

4.4、Modify

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class Modify implements IOperation{
    public void work(BookList bookList) {
        //只能改价格
        System.out.println("==修改图书==");

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

        int index=-1;
        int currentUsedSize = bookList.getUsedSize();
        for (int i = 0; i < currentUsedSize; i++) {
            Book book = bookList.getPosBooks(i);
            if(book.getName().equals(name)) {//字符串的比较,用equals
                index=i;
                break;
            }
        }
        if(index==-1){
            System.out.println("没有你要修改的书!");
        }else{
            System.out.println("请输入你要修改成的相关信息:>");
            System.out.println("请输入图书名字:>");
            String mName = scanner.nextLine();
            System.out.println("请输入作者姓名:>");
            String mAuthor = scanner.nextLine();
            System.out.println("请输入图书价格:>");
            int mPrice= scanner.nextInt();
            scanner.nextLine();//接收上一步留下的回车键
            System.out.println("请输入图书类型:>");
            String mType = scanner.nextLine();

            //创建一个Book类型的对象存储这本书
            Book book = new Book(mName,mAuthor,mPrice,mType);
            //把书放进书架(这里相当于尾插)

            bookList.setPosBooks(index,book);
            System.out.println("修改成功!");
        }
    }
}

4.5、Display

package operation;
import book.BookList;

public class Display implements IOperation{
    public void work(BookList bookList) {
        System.out.println("==显示图书==");

        int currentUserSize = bookList.getUsedSize();
        for (int i = 0; i < currentUserSize; i++) {
            System.out.println(bookList.getPosBooks(i));
        }
    }
}

4.6、Exit

package operation;
import book.BookList;

public class Exit implements IOperation{
    public void work(BookList bookList) {
        System.out.println("==退出系统==");
        System.exit(-1);
    }
}

4.7、Borrow

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class Borrow implements IOperation{
    public void work(BookList bookList) {
        System.out.println("==借阅图书==");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入图书名字:>");
        String name = scanner.nextLine();
        int currentUsedSize = bookList.getUsedSize();
        for (int i = 0; i < currentUsedSize; i++) {
            Book book = bookList.getPosBooks(i);
            if(book.getName().equals(name)) {//字符串的比较,用equals
                bookList.getPosBooks(i).setBorrowed(true);
                System.out.println("借阅成功!");
                return;
            }
        }
        System.out.println("没有你要借阅的书!");
    }
}

4.8、Return

package operation;
import book.Book;
import book.BookList;
import java.util.Scanner;

public class Return implements IOperation{
    public void work(BookList bookList) {
        System.out.println("==归还图书==");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入图书名字:>");
        String name = scanner.nextLine();
        int currentUsedSize = bookList.getUsedSize();
        for (int i = 0; i < currentUsedSize; i++) {
            Book book = bookList.getPosBooks(i);
            if(book.getName().equals(name)) {//字符串的比较,用equals
                bookList.getPosBooks(i).setBorrowed(false);
                System.out.println("归还成功!");
                return;
            }
        }
        System.out.println("没有你要归还的书!");
    }
}

总结

1、找对象

面向对象和面向过程不一样,面向过程只是一种解决问题的方法,面向对象是根据对象去解决问题。 所以,面向对象第一步是找出对象。

  1. 对象第一类:人(User)(还分管理员(AdminUser)和普通用户(NormalUser),User是它俩的父类)
  2. 对象第二类:书(Book),有了书还得有书架(BookList)
  3. 对象第三类:增删查改等操作(也可以在BookList中创建方法实现增删查改)

2、整体把握,构建框架

面向对象要有整体的思维,整体的框架。不是先完成一个函数就去测试,而是应该先把框架架构出来比如:

  1. 图书管理User类被AdminUserNormalUser继承,3个类。
  2. BookBookList,5个类。
  3. Add,Delete,Find,Modify,Display,Borrow,Return,Exit,这八个类实现一个接口IOperation。共16个类,1个接口。
    注意:当然,这些框架也是一步一步写才知道需要用到继承,用到接口,用到抽象类。

3、选择合适的方法位置

比如在上面代码中,

  1. login登录方法在main类中操作,因为它只需要返回AdminUser或NormalUser对象,不需要访问其它。
  2. 整合操作的方法doOperation在父类User中操作,从而能够访问iOpreations接口数组,进而访问Add等增删查改的work()方法

最后:希望各位大佬批评指正!

你可能感兴趣的:(【JavaSE】,java,算法,开发语言)