news 2026/9/20 9:40:41

【Java SE】基于多态与接口实现图书管理系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Java SE】基于多态与接口实现图书管理系统

文章目录

  • 一、系统整体设计:分层与职责划分
    • 系统模块结构
  • 二、核心模块详解:从数据到功能
    • 1. Book包:数据封装
      • 1.1 Book类:图书实体
      • 1.2 BookList类:书架管理
    • 2. User包:多态的核心体现
      • 2.1 User抽象类:用户模板
      • 2.2 AdminUser:管理员子类
      • 2.3 NormalUser:普通用户子类
    • 3. IOperations包:接口解耦业务功能
      • 3.1 IOperation接口:操作标准
      • 3.2 核心操作类实现(示例)
        • (1)FindOperation:查找图书
        • (2)BorrowOperation:借阅图书
        • (3)DelOperation: 删除图书
  • 三、系统入口:Main类的流程控制
    • 1. 初始化书架
    • 2. 用户登录
    • 3. 循环执行操作
  • 四、系统亮点:面向对象思想的落地
    • 1. 封装性
    • 2. 继承与多态
    • 3. 接口解耦(开闭原则)

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

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

系统模块结构

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

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

1. Book包:数据封装

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

1.1 Book类:图书实体

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

publicclassBook{// 私有属性:保证数据不被外部直接修改privateStringname;// 书名(唯一标识)privateStringauthor;// 作者privateintprice;// 价格privateStringtype;// 类型privatebooleanisBorrowed;// 借阅状态// 构造方法:初始化图书信息(借阅状态默认false,即未借出)publicBook(Stringname,Stringauthor,intprice,Stringtype){this.name=name;this.author=author;this.price=price;this.type=type;this.isBorrowed=false;// 初始未借出}// getter/setter:对外提供安全的访问接口publicbooleanisBorrowed(){returnisBorrowed;}publicvoidsetBorrowed(booleanborrowed){isBorrowed=borrowed;}// 其他getter/setter省略...// 重写toString:自定义图书打印格式(包含借阅状态)@OverridepublicStringtoString(){return"Book{"+"name='"+name+'\''+", author='"+author+'\''+", price="+price+", type='"+type+'\''+((isBorrowed)?", 已借出":", 未借出")+// 动态显示借阅状态'}';}}

1.2 BookList类:书架管理

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

核心逻辑:

  • 初始化时默认添加3本经典小说(《三国演义》《西游记》《红楼梦》);
  • 通过setBook()getBook()操作指定位置的图书;
  • 通过getUsedSize()setUsedSize()管理有效图书数量,避免数组越界。
publicclassBookList{privateBook[]books=newBook[10];// 固定大小的书架(最多10本)privateintusedSize;// 有效图书数量(避免遍历空位置)// 构造方法:初始化默认图书publicBookList(){books[0]=newBook("三国演义","罗贯中",10,"小说");books[1]=newBook("西游记","吴承恩",59,"小说");books[2]=newBook("红楼梦","曹雪芹",16,"小说");this.usedSize=3;// 初始3本有效图书}// 对外提供书架操作接口publicBookgetBook(intpos){returnbooks[pos];}publicvoidsetBook(Bookbook,intpos){this.books[pos]=book;}publicintgetUsedSize(){returnusedSize;}publicvoidsetUsedSize(intusedSize){this.usedSize=usedSize;}}

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

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

2.1 User抽象类:用户模板

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

publicabstractclassUser{protectedStringname;// 用户名// 存储当前用户可执行的操作(多态的关键:子类初始化不同操作数组)protectedIOperation[]iOperations;// 构造方法:初始化用户名publicUser(Stringname){this.name=name;}// 抽象方法:不同用户的菜单不同,由子类实现publicabstractintmenu();// 统一执行操作:通过操作数组索引调用对应操作(解耦流程与具体功能)publicvoiddoIOperations(intch,BookListbookList){iOperations[ch].work(bookList);}}

2.2 AdminUser:管理员子类

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

  • 构造方法中初始化iOperations数组,顺序对应菜单选项;
  • 实现menu()方法,打印管理员专属菜单并返回用户选择。
publicclassAdminUserextendsUser{// 初始化管理员可执行的操作(索引0=退出,1=查找,2=新增,3=删除,4=显示)publicAdminUser(Stringname){super(name);this.iOperations=newIOperation[]{newExitOperation(),// 0.退出newFindOperation(),// 1.查找newAddOperation(),// 2.新增newDelOperation(),// 3.删除newShowOperation()// 4.显示};}// 管理员菜单:返回用户选择的操作索引@Overridepublicintmenu(){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("请输入你的选择:");returnnewScanner(System.in).nextInt();}}

2.3 NormalUser:普通用户子类

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

publicclassNormalUserextendsUser{// 初始化普通用户可执行的操作(索引0=退出,1=查找,2=借阅,3=归还)publicNormalUser(Stringname){super(name);this.iOperations=newIOperation[]{newExitOperation(),// 0.退出newFindOperation(),// 1.查找newBorrowOperation(),// 2.借阅newReturnOperation()// 3.归还};}// 普通用户菜单@Overridepublicintmenu(){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("请输入你的选择:");returnnewScanner(System.in).nextInt();}}

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

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

3.1 IOperation接口:操作标准

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

publicinterfaceIOperation{// 所有操作的统一入口:接收BookList对象,操作书架数据voidwork(BookListbookList);}

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

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

(1)FindOperation:查找图书

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

publicclassFindOperationimplementsIOperation{@Overridepublicvoidwork(BookListbookList){System.out.println("查找图书...");System.out.println("输入待查找的书名:");Stringname=newScanner(System.in).nextLine();// 遍历有效图书(仅遍历usedSize个,避免空指针)for(inti=0;i<bookList.getUsedSize();i++){Bookbook=bookList.getBook(i);if(book.getName().equals(name)){System.out.println(book);// 调用Book的toString()return;}}System.out.println("该图书不存在");}}
(2)BorrowOperation:借阅图书

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

publicclassBorrowOperationimplementsIOperation{@Overridepublicvoidwork(BookListbookList){System.out.println("借阅图书...");System.out.println("输入待借阅书名:");Stringname=newScanner(System.in).nextLine();for(inti=0;i<bookList.getUsedSize();i++){Bookbook=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);}}
(3)DelOperation: 删除图书
publicclassDelOPimplementsIOperation{@Overridepublicvoidwork(BookListbookList){System.out.println("删除图书...");System.out.println("输入待删除的书名:");Scannerscan=newScanner(System.in);Stringname=scan.nextLine();intcurSize=bookList.getSize();for(inti=0;i<curSize;i++){if(name.equals(bookList.getBook(i).getName())){//依次向前移for(intj=i;j<curSize-1;j++){Bookbook=bookList.getBook(j+1);bookList.setBook(book,j);}bookList.setSize(curSize-1);System.out.println("成功删除!");return;}}System.out.println("该图书不存在");}}

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

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

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

1. 初始化书架

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

BookListbookList=newBookList();

2. 用户登录

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

publicstaticUserlogin(){Scannerscan=newScanner(System.in);System.out.println("你的姓名:");Stringname=scan.nextLine();System.out.println("请输入你的身份:1.管理员 2.普通用户");intch=scan.nextInt();if(ch==1){returnnewAdminUser(name);// 向上转型为User}else{returnnewNormalUser(name);// 向上转型为User}}

3. 循环执行操作

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

  • user.menu():根据实际用户类型(管理员/普通)调用对应菜单;
  • user.doIOperations():根据用户选择的索引,调用对应操作。
publicstaticvoidmain(String[]args){BookListbookList=newBookList();Useruser=login();// 向上转型:User指向AdminUser/NormalUserwhile(true){intchoice=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数组的元素顺序,无需改动操作类本身。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 9:37:58

Intel RealSense D435i在ROS中的深度集成与工程调优

1. 这不是普通摄像头&#xff1a;D435i为什么在ROS生态里成了“刚需级”传感器Intel RealSense D435i 不是插上就能用的USB摄像头&#xff0c;它是一套带IMU的主动式立体视觉系统——这句话我第一次调试失败后&#xff0c;在实验室白板上写了三遍。它能同时输出RGB图像、深度图…

作者头像 李华
网站建设 2026/9/20 9:37:03

Linux cd命令详解:路径、OLDPWD与CDPATH的实用指南

在 Linux 终端里&#xff0c;cd 命令通常是大多数新手继 ls 之后认识的第二个命令。它看起来简单到让人懒得深究&#xff1a;cd 后面跟个目录名&#xff0c;按下回车&#xff0c;位置就变了。可一旦把场景放到真实运维和开发环境里&#xff0c;事情就没那么简单——有人切进一个…

作者头像 李华
网站建设 2026/9/20 9:34:31

BrewUI:给Homebrew套上可视化外壳,让命令行工具拥有图形界面

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 9:33:05

STM32裸机启动流程详解:从复位向量到main函数执行

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 9:29:19

AI率太高?从检测原理到复述改写,一套降低AIGC检测率的实战指南

先说我自己的结论&#xff1a;AI率高不高&#xff0c;其实从你按下回车让ChatGPT写第一段话的时候就已经注定了。后面所有降AI率的操作&#xff0c;都是在给前面偷的懒买单。这篇文章我会把自己从"ChatGPT生成初稿"到"通过学校AIGC检测"的全过程拆开讲&…

作者头像 李华
网站建设 2026/9/20 9:28:30

直流直流变换器设计入门:从Buck/Boost到拓扑选型与调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华