一、实验场景
某大学图书馆需要管理两类资源:图书(Book) 和期刊(Journal)。两类资源都有基本信息(编号、名称、作者),但图书有 ISBN 编号,期刊有出版周期(如 "月刊""季刊")。此外:
图书支持 "借阅" 和 "归还" 操作;
期刊支持 "借阅""归还" 和 "电子版下载" 操作;
图书馆需要统计资源总数、按类型查询资源信息。
二、实验要求
- 设计核心接口
Borrowable接口:定义可借阅资源的规范,包含方法:
void borrow(String userId):记录借阅操作(参数为借阅人 ID);
void returnRes(String userId):记录归还操作(参数为借阅人 ID)。
Downloadable接口:定义可下载资源的规范,包含方法:
String download():返回下载链接(如 "https://lib.example.com/journals/xxx")。 - 设计父类与子类
父类Resource(资源基类):
成员变量:protected String id(资源编号)、protected String name(名称)、protected String author(作者);
构造方法:public Resource(String id, String name, String author);
普通方法:public void showBasicInfo():打印 "资源编号:XXX,名称:XXX,作者:XXX";
抽象方法:public abstract String getType():返回资源类型(如 "图书""期刊",由子类实现)。
子类Book(图书,继承Resource,实现Borrowable):
新增成员:private String isbn(ISBN 编号);
构造方法:public Book(String id, String name, String author, String isbn);
实现Borrowable接口的borrow()和returnRes():
borrow():打印 "图书《XXX》(ISBN:XXX)被用户 XXX 借阅";
returnRes():打印 "图书《XXX》(ISBN:XXX)被用户 XXX 归还";
重写getType():返回 "图书";
新增方法:public String getIsbn():返回 ISBN 编号。
子类Journal(期刊,继承Resource,实现Borrowable和Downloadable):
新增成员:private String period(出版周期,如 "月刊");
构造方法:public Journal(String id, String name, String author, String period);
实现Borrowable接口的方法:
borrow():打印 "期刊《XXX》(周期:XXX)被用户 XXX 借阅";
returnRes():打印 "期刊《XXX》(周期:XXX)被用户 XXX 归还";
实现Downloadable接口的download():返回 "https://lib.example.com/journals/"+ 资源编号;
重写getType():返回 "期刊";
新增方法:public String getPeriod():返回出版周期。 - 设计管理类
LibraryManager类:管理所有资源,包含:
成员变量:private List resources(存储资源的集合);
构造方法:初始化集合(resources = new ArrayList<>());
方法:
public void addResource(Resource res):向集合添加资源(支持多态,可添加Book或Journal);
public void showAllResources():遍历集合,调用每个资源的showBasicInfo()和getType(),打印所有资源信息;
public int countByType(String type):统计指定类型(如 "图书")的资源数量。 - 测试类
LibraryTest类(含main方法):
创建LibraryManager对象;
添加 3 个资源:
图书:编号 "B001",名称 "Java 编程思想",作者 "Bruce Eckel",ISBN "9787111213826";
期刊:编号 "J001",名称 "计算机学报",作者 "中国计算机学会",周期 "月刊";
图书:编号 "B002",名称 "数据结构",作者 "严蔚敏",ISBN "9787302147510";
调用showAllResources()打印所有资源;
调用countByType("图书")并打印结果(预期为 2);
对 "Java 编程思想" 执行借阅(用户 "U1001")和归还操作;
对 "计算机学报" 执行借阅(用户 "U1002")、归还和下载操作,打印下载链接。
三、解析
我们可以首先创建一个包,将所有的内容放在这个包里面。如下图的包。

3.1 接口定义
两个接口需要单独定义:
首先我们在本次实验的包里面创建接口:
如下图所示,依然选择创建java类,但是在命名的时候选择接口而不是类。


创建好两个接口后如图所示。

两个接口的代码如下所示。


3.2 父类与子类
父类Resource
根据题意,首先创建父类Resource(资源基类)

这是一个抽象类,功能如下:
成员变量:protected String id(资源编号)、protected String name(名称)、protected String author(作者);
构造方法:public Resource(String id, String name, String author);
普通方法:public void showBasicInfo():打印 "资源编号:XXX,名称:XXX,作者:XXX";
抽象方法:public abstract String getType():返回资源类型(如 "图书""期刊",由子类实现)。

子类Book
子类Book(图书,继承Resource,实现Borrowable):
新增成员:private String isbn(ISBN 编号);
构造方法:public Book(String id, String name, String author, String isbn);
实现Borrowable接口的borrow()和returnRes():
borrow():打印 "图书《XXX》(ISBN:XXX)被用户 XXX 借阅";
returnRes():打印 "图书《XXX》(ISBN:XXX)被用户 XXX 归还";
重写getType():返回 "图书";
新增方法:public String getIsbn():返回 ISBN 编号。
我们在写上继承Resource,实现接口Borrowable后报错,这是为什么?
这是因为我们理论课讲的普通类 实现一个接口,就要实现它的所有抽象方法。

这个时候,按住alt+enter,选择实现方法

这个时候即可选择我们要实现的方法,

这个时候会帮我们自动实现所有的方法

这个时候根据题意完成代码,完整代码如下所示:

子类Journal
期刊类同理:

3.3设计管理类
LibraryManager类:管理所有资源,包含:
成员变量:private List resources(存储资源的集合);
构造方法:初始化集合(resources = new ArrayList<>());
方法:
public void addResource(Resource res):向集合添加资源(支持多态,可添加Book或Journal);
public void showAllResources():遍历集合,调用每个资源的showBasicInfo()和getType(),打印所有资源信息;
public int countByType(String type):统计指定类型(如 "图书")的资源数量。
依然根据题意一步一步完成,管理类代码如下:
java
import java.util.ArrayList;
import java.util.List;
// 图书馆管理类
public class LibraryManager {
private List<Resource> resources;
public LibraryManager() {
resources = new ArrayList<>();
}
public void addResource(Resource res) {
resources.add(res);
}
public void showAllResources() {
System.out.println("\n=== 图书馆资源列表 ===");
for (Resource res : resources) {
res.showBasicInfo(); // 调用父类方法(多态)
System.out.println("资源类型:" + res.getType()); // 调用子类重写的抽象方法
}
}
public int countByType(String type) {
int count = 0;
for (Resource res : resources) {
if (res.getType().equals(type)) {
count++;
}
}
return count;
}
}
此处代码使用了ArrayList,大家学习过数据结构,
3.4 测试类
LibraryTest类(含main方法):
创建LibraryManager对象;
添加 3 个资源:
图书:编号 "B001",名称 "Java 编程思想",作者 "Bruce Eckel",ISBN "9787111213826";
期刊:编号 "J001",名称 "计算机学报",作者 "中国计算机学会",周期 "月刊";
图书:编号 "B002",名称 "数据结构",作者 "严蔚敏",ISBN "9787302147510";
调用showAllResources()打印所有资源;
调用countByType("图书")并打印结果(预期为 2);
对 "Java 编程思想" 执行借阅(用户 "U1001")和归还操作;
对 "计算机学报" 执行借阅(用户 "U1002")、归还和下载操作,打印下载链接。
java
// 测试类
public class LibraryTest {
public static void main(String[] args) {
// 创建图书馆管理器
LibraryManager manager = new LibraryManager();
// 添加资源(多态:父类引用指向子类对象)
Resource book1 = new Book("B001", "Java编程思想", "Bruce Eckel", "9787111213826");
Resource journal1 = new Journal("J001", "计算机学报", "中国计算机学会", "月刊");
Resource book2 = new Book("B002", "数据结构", "严蔚敏", "9787302147510");
manager.addResource(book1);
manager.addResource(journal1);
manager.addResource(book2);
// 显示所有资源
manager.showAllResources();
// 统计图书数量
int bookCount = manager.countByType("图书");
System.out.println("\n图书总数:" + bookCount); // 输出:2
// 图书借阅与归还
System.out.println("\n=== 图书操作 ===");
Book javaBook = (Book) book1; // 向下转型(因需调用Book特有方法,或直接用book1调用Borrowable方法)
javaBook.borrow("U1001");
javaBook.returnRes("U1001");
// 期刊操作(借阅、归还、下载)
System.out.println("\n=== 期刊操作 ===");
Journal compJournal = (Journal) journal1;
compJournal.borrow("U1002");
compJournal.returnRes("U1002");
System.out.println("期刊下载链接:" + compJournal.download());
}
}
3.5 最后形态

3.6 测试结果
