• Java-图书项目(封装、继承、多态)


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

    前言

    学习目标:

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

    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函数测试
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    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;
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    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) ? "未借出" : "已借出") +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    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操作
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    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("增添成功!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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("删除成功!");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    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("没有你要查找的书!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    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("修改成功!");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    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));
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.6、Exit

    package operation;
    import book.BookList;
    
    public class Exit implements IOperation{
        public void work(BookList bookList) {
            System.out.println("==退出系统==");
            System.exit(-1);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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("没有你要借阅的书!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    总结

    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()方法

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

  • 相关阅读:
    VL3 奇偶校验
    仿热血江湖游戏类43
    Linux内核顶层Makefile前期工作分析二
    顺丰快递:请签收MySQL灵魂十连
    APP自动化测试-5.触屏操作及toast处理
    Linux文件和目录常用命令
    电子电子架构——AUTOSAR信息安全机制有哪些?(上)
    Openlayers | Cesium 在线生成随机点线面坐标数据
    华为的仓颉和ArkTS这两门语言有什么区别
    Aspectj基础原理解析
  • 原文地址:https://blog.csdn.net/m0_63979882/article/details/126595813