【Java SE】基于多态与接口实现图书管理系统:从设计到编码全解析

一、系统整体设计:分层与职责划分

一个良好的系统设计首先要明确模块边界和职责。本图书管理系统采用模块化分层设计,将代码按功能划分为5个核心包,每个包承担独立职责,避免代码耦合。

系统模块结构

包名(Package)核心类/接口职责描述
BookBookBookList封装图书数据(Book)和书架管理(BookList
UserUser(抽象)、AdminUserNormalUser封装用户信息,区分管理员和普通用户的不同权限
IOperationsIOperation(接口)、各操作类定义所有业务操作的标准接口,实现具体功能(查找、新增、借阅等)
根包Main系统入口,负责用户登录、流程控制

二、核心模块详解:从数据到功能

1. Book包:数据封装

Book包是系统的“数据层”,负责存储图书信息和管理书架,核心是封装思想的体现——将数据(图书属性)和操作(get/set方法)封装在类内部,对外暴露安全的访问接口。

1.1 Book类:图书实体

Book类代表一本图书,包含5个核心属性,通过private修饰保证数据安全,通过getter/setter提供访问入口,并重写toString()方便打印图书信息。

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;
        this.isBorrowed = false; // 初始未借出
    }

    // getter/setter:对外提供安全的访问接口
    public boolean isBorrowed() { return isBorrowed; }
    public void setBorrowed(boolean borrowed) { isBorrowed = borrowed; }
    // 其他getter/setter省略...

    // 重写toString:自定义图书打印格式(包含借阅状态)
    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ((isBorrowed)?", 已借出":", 未借出")+ // 动态显示借阅状态
                '}';
    }
}

1.2 BookList类:书架管理

BookList类相当于“书架”,管理一个Book数组,并记录有效图书数量(usedSize)。它提供了图书的增删查改入口,是数据操作的“中间层”。

核心逻辑:

  • 初始化时默认添加3本经典小说(《三国演义》《西游记》《红楼梦》);
  • 通过setBook()getBook()操作指定位置的图书;
  • 通过getUsedSize()setUsedSize()管理有效图书数量,避免数组越界。
public class BookList {
    private Book[] books = new Book[10]; // 固定大小的书架(最多10本)
    private int usedSize; // 有效图书数量(避免遍历空位置)

    // 构造方法:初始化默认图书
    public BookList(){
        books[0] = new Book("三国演义","罗贯中",10,"小说");
        books[1] = new Book("西游记","吴承恩",59,"小说");
        books[2] = new Book("红楼梦","曹雪芹",16,"小说");
        this.usedSize = 3; // 初始3本有效图书
    }

    // 对外提供书架操作接口
    public Book getBook(int pos) { return books[pos]; }
    public void setBook(Book book, int pos) { this.books[pos] = book; }
    public int getUsedSize() { return usedSize; }
    public void setUsedSize(int usedSize) { this.usedSize = usedSize; }
}

2. User包:多态的核心体现

User包是系统的“用户层”,通过抽象类+子类的结构实现多态,让不同用户(管理员/普通用户)拥有不同的菜单和操作权限,而无需修改核心流程。

2.1 User抽象类:用户模板

User类被定义为抽象类,它不直接实例化,而是作为所有用户的“模板”,定义通用属性(name)和抽象方法(menu()),并通过IOperation[]存储当前用户可执行的操作。

public abstract class User {
    protected String name; // 用户名
    // 存储当前用户可执行的操作(多态的关键:子类初始化不同操作数组)
    protected IOperation[] iOperations;

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

    // 抽象方法:不同用户的菜单不同,由子类实现
    public abstract int menu();

    // 统一执行操作:通过操作数组索引调用对应操作(解耦流程与具体功能)
    public void doIOperations(int ch, BookList bookList) {
        iOperations[ch].work(bookList);
    }
}

2.2 AdminUser:管理员子类

管理员拥有最高权限,可执行“查找、新增、删除、显示、退出”5个操作。核心逻辑:

  • 构造方法中初始化iOperations数组,顺序对应菜单选项;
  • 实现menu()方法,打印管理员专属菜单并返回用户选择。
public class AdminUser extends User {
    // 初始化管理员可执行的操作(索引0=退出,1=查找,2=新增,3=删除,4=显示)
    public AdminUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{
                new ExitOperation(),   // 0.退出
                new FindOperation(),   // 1.查找
                new AddOperation(),    // 2.新增
                new DelOperation(),    // 3.删除
                new ShowOperation()    // 4.显示
        };
    }

    // 管理员菜单:返回用户选择的操作索引
    @Override
    public int menu() {
        System.out.println("欢迎 " + name + " 来到图书管理系统");
        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("请输入你的选择:");
        return new Scanner(System.in).nextInt();
    }
}

2.3 NormalUser:普通用户子类

普通用户权限有限,仅可执行“查找、借阅、归还、退出”4个操作。逻辑与管理员类似,但iOperations数组和菜单选项不同。

public class NormalUser extends User {
    // 初始化普通用户可执行的操作(索引0=退出,1=查找,2=借阅,3=归还)
    public NormalUser(String name) {
        super(name);
        this.iOperations = new IOperation[]{
                new ExitOperation(),   // 0.退出
                new FindOperation(),   // 1.查找
                new BorrowOperation(), // 2.借阅
                new ReturnOperation()  // 3.归还
        };
    }

    // 普通用户菜单
    @Override
    public int menu() {
        System.out.println("欢迎 " + name + " 来到图书管理系统");
        System.out.println("*****普通用户菜单******");
        System.out.println("1.查找图书");
        System.out.println("2.借阅图书");
        System.out.println("3.归还图书");
        System.out.println("0.退出");
        System.out.println("请输入你的选择:");
        return new Scanner(System.in).nextInt();
    }
}

3. IOperations包:接口解耦业务功能

IOperations包是系统的“功能层”,通过接口定义所有业务操作的标准,让具体功能(如查找、借阅)与用户流程解耦——新增功能时只需实现接口,无需修改现有代码(符合开闭原则)。

3.1 IOperation接口:操作标准

IOperation接口定义了一个抽象方法work(BookList bookList),所有业务操作类都必须实现该方法,保证操作的“统一性”。

public interface IOperation {
    // 所有操作的统一入口:接收BookList对象,操作书架数据
    void work(BookList bookList);
}

3.2 核心操作类实现(示例)

以“查找图书”和“借阅图书”为例,展示具体功能的实现逻辑:

(1)FindOperation:查找图书

逻辑:接收用户输入的书名,遍历书架匹配,找到则打印图书信息,未找到则提示。

public class FindOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("查找图书...");
        System.out.println("输入待查找的书名:");
        String name = new Scanner(System.in).nextLine();

        // 遍历有效图书(仅遍历usedSize个,避免空指针)
        for (int i = 0; i < bookList.getUsedSize(); i++) {
            Book book = bookList.getBook(i);
            if (book.getName().equals(name)) {
                System.out.println(book); // 调用Book的toString()
                return;
            }
        }
        System.out.println("该图书不存在");
    }
}
(2)BorrowOperation:借阅图书

逻辑:匹配书名后,先判断图书是否已借出,未借出则修改isBorrowed状态为true,已借出则提示。

public class BorrowOperation implements IOperation {
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书...");
        System.out.println("输入待借阅书名:");
        String name = new Scanner(System.in).nextLine();

        for (int i = 0; i < bookList.getUsedSize(); i++) {
            Book book = bookList.getBook(i);
            if (book.getName().equals(name)) {
                if (book.isBorrowed()) { // 已借出
                    System.out.println("该书已被借出");
                    return;
                }
                book.setBorrowed(true); // 标记为已借出
                System.out.println("借阅成功");
                return;
            }
        }
        System.out.println("未找到" + name);
    }
}

其他操作类(如AddOperation新增、DelOperation删除)逻辑类似,均围绕“用户输入→数据校验→操作书架”的流程实现,此处不再赘述。

三、系统入口:Main类的流程控制

Main类是系统的“控制层”,负责串联所有模块,核心流程分为3步:

1. 初始化书架

创建BookList对象,自动加载3本默认图书。

BookList bookList = new BookList();

2. 用户登录

接收用户名和身份(管理员/普通用户),返回对应的User子类对象(向上转型,多态的前提)。

public static User login() {
    Scanner scan = new Scanner(System.in);
    System.out.println("你的姓名:");
    String name = scan.nextLine();

    System.out.println("请输入你的身份:1.管理员   2.普通用户");
    int ch = scan.nextInt();
    if (ch == 1) {
        return new AdminUser(name); // 向上转型为User
    } else {
        return new NormalUser(name); // 向上转型为User
    }
}

3. 循环执行操作

通过while(true)实现循环菜单,核心是多态调用

  • user.menu():根据实际用户类型(管理员/普通)调用对应菜单;
  • user.doIOperations():根据用户选择的索引,调用对应操作。
public static void main(String[] args) {
    BookList bookList = new BookList();
    User user = login(); // 向上转型:User指向AdminUser/NormalUser

    while (true) {
        int choice = user.menu(); // 多态:调用子类的menu()
        user.doIOperations(choice, bookList); // 多态:调用对应操作
    }
}

四、系统亮点:面向对象思想的落地

这个图书管理系统的核心价值,在于将面向对象的三大特性和设计原则融入实际开发:

1. 封装性

  • Book类隐藏图书属性,通过getter/setter控制访问;
  • BookList类隐藏数组操作,对外提供安全的书架管理接口。

2. 继承与多态

  • User抽象类定义通用行为,子类(AdminUser/NormalUser)实现差异化功能;
  • 向上转型(User user = new AdminUser())让代码无需区分用户类型,直接调用通用方法(menu()/doIOperations())。

3. 接口解耦(开闭原则)

  • 新增功能时(如“修改图书信息”),只需新建类实现IOperation接口,无需修改UserMain的代码;
  • 不同用户的权限调整,只需修改iOperations数组的元素顺序,无需改动操作类本身。

五、扩展建议:让系统更完善

当前系统已实现核心功能,但仍有优化空间,可作为后续扩展方向:

  1. 书架扩容:将Book[]改为ArrayList<Book>,支持动态扩容;
  2. 用户密码验证:在login()中增加密码输入和校验(可存储在数组或文件中);
  3. 图书ID唯一标识:避免书名重复导致的操作错误(如两本《西游记》);
  4. 数据持久化:用IO流将图书信息存储到文件(如books.txt),避免程序重启后数据丢失;
  5. 异常处理:增加try-catch捕获用户输入错误(如输入非数字的菜单选项)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值